@oiij/use
Version:
Som Composable Functions for Vue 3
114 lines (112 loc) • 2.94 kB
JavaScript
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const __vueuse_core = require_rolldown_runtime.__toESM(require("@vueuse/core"));
const vue = require_rolldown_runtime.__toESM(require("vue"));
//#region src/composables/use-type-writer.ts
function useTypeWriter(value, options) {
const { step = 1, interval = 50, enabled = true } = options ?? {};
const typeIndex = (0, vue.ref)(0);
const paused = (0, vue.ref)(false);
const ended = (0, vue.ref)(false);
const isTyping = (0, vue.ref)(false);
const typedValue = (0, vue.computed)(() => enabled ? value.value.slice(0, typeIndex.value) : value.value);
const progress = (0, vue.computed)(() => Number(Math.min(typeIndex.value / value.value.length * 100, 100).toFixed(2)));
let timer = null;
const onStatEvent = (0, __vueuse_core.createEventHook)();
const onStopEvent = (0, __vueuse_core.createEventHook)();
const onUpdateEvent = (0, __vueuse_core.createEventHook)();
(0, vue.watch)(value, (newValue, oldValue) => {
if (!oldValue) {
typeIndex.value = 0;
start();
return;
}
if (newValue.startsWith(oldValue)) start();
else {
typeIndex.value = 0;
start();
}
}, { immediate: true });
function start() {
if (timer) clearTimeout(timer);
if (!enabled) {
typeIndex.value = value.value.length;
ended.value = true;
isTyping.value = false;
paused.value = false;
onStopEvent.trigger(typedValue.value);
return;
}
isTyping.value = true;
paused.value = false;
ended.value = false;
onStatEvent.trigger();
function run() {
typeIndex.value += step;
onUpdateEvent.trigger({
index: typeIndex.value,
value: typedValue.value
});
if (typeIndex.value >= value.value.length) {
typeIndex.value = value.value.length;
ended.value = true;
isTyping.value = false;
onStopEvent.trigger(typedValue.value);
return;
}
timer = setTimeout(run, interval);
}
timer = setTimeout(run, interval);
}
function pause() {
if (timer) clearTimeout(timer);
paused.value = true;
isTyping.value = false;
ended.value = false;
}
function resume() {
if (timer) clearTimeout(timer);
start();
}
function restart() {
if (timer) clearTimeout(timer);
typeIndex.value = 0;
(0, vue.nextTick)(() => {
start();
});
}
function stop() {
if (timer) clearTimeout(timer);
isTyping.value = false;
paused.value = false;
ended.value = true;
typeIndex.value = value.value.length;
onStopEvent.trigger(typedValue.value);
}
function destroy() {
if (timer) clearTimeout(timer);
timer = null;
isTyping.value = false;
paused.value = false;
ended.value = false;
typeIndex.value = 0;
}
return {
typeIndex,
paused,
ended,
isTyping,
typedValue,
progress,
start,
pause,
resume,
restart,
stop,
destroy,
onStat: onStatEvent.on,
onStop: onStopEvent.on,
onUpdate: onUpdateEvent.on
};
}
//#endregion
exports.useTypeWriter = useTypeWriter;