UNPKG

@asasugar-use/vue3-typewriter

Version:
86 lines (85 loc) 2.73 kB
import { defineComponent, useCssVars, useAttrs, ref, computed, watch, onUnmounted, openBlock, createElementBlock, createElementVNode, mergeProps, unref, toDisplayString, createCommentVNode } from "vue"; const _hoisted_1 = { key: 0 }; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "vue3-typewriter", props: { text: {}, typingSpeed: { default: 100 }, cursorColor: { default: "red" }, cursorShow: { type: Boolean, default: true } }, emits: ["completed"], setup(__props, { emit: __emit }) { useCssVars((_ctx) => ({ "3338934b": props.cursorColor })); const props = __props; const emit = __emit; const attrs = useAttrs(); const displayedText = ref(""); const isFinished = ref(false); const isCursorHidden = computed(() => !props.cursorShow || isFinished.value); let currentIndex = 0; let lastTime = 0; let animationFrameId; const typeWriterEffect = (time) => { if (currentIndex < props.text.length) { if (!lastTime) lastTime = time; const timeDifference = time - lastTime; if (timeDifference > props.typingSpeed) { displayedText.value += props.text.charAt(currentIndex); currentIndex++; lastTime = time; } animationFrameId = requestAnimationFrame(typeWriterEffect); } else { isFinished.value = true; emit("completed"); } }; watch( () => props.text, (newText, oldText) => { if (newText.length < oldText.length) { displayedText.value = newText.slice(0, currentIndex); } isFinished.value = false; animationFrameId = requestAnimationFrame(typeWriterEffect); } ); onUnmounted(() => { cancelAnimationFrame(animationFrameId); }); return (_ctx, _cache) => { return displayedText.value ? (openBlock(), createElementBlock("div", _hoisted_1, [ createElementVNode("span", mergeProps({ ...unref(attrs) }, { class: ["text", { "cursor-hidden": isCursorHidden.value }] }), toDisplayString(displayedText.value), 17) ])) : createCommentVNode("", true); }; } }); const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const Vue3Typewriter = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4c7ca741"]]); let installed = false; function install(app) { if (installed) return; installed = true; app.component("Vue3Typewriter", Vue3Typewriter); } const plugin = { install }; if (typeof window !== "undefined" && window.Vue) { window.Vue.use(plugin); } export { Vue3Typewriter as default, install };