UNPKG

@minto-ai/type-writer

Version:

流式打字机效果组件,提供逐字符显示文本的打字机效果

163 lines (162 loc) 4.21 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var TypeWriterStatus = /* @__PURE__ */ ((TypeWriterStatus2) => { TypeWriterStatus2["PENDING"] = "pending"; TypeWriterStatus2["EXECUTING"] = "executing"; TypeWriterStatus2["COMPLETED"] = "completed"; return TypeWriterStatus2; })(TypeWriterStatus || {}); class EventBus { constructor() { __publicField(this, "listeners", /* @__PURE__ */ new Map()); } on(eventName, callback) { const callbacks = this.listeners.get(eventName); if (callbacks) { callbacks.push(callback); } else { this.listeners.set(eventName, [callback]); } } emit(eventName, data) { const callbacks = this.listeners.get(eventName); if (callbacks) { callbacks.forEach((callback) => { callback(data); }); } } clear() { this.listeners.clear(); } } let eventBusInstance = null; function createEventBus() { if (!eventBusInstance) { eventBusInstance = new EventBus(); } return eventBusInstance; } const defaultOptions = { speed: 100 }; class TypeWriter { constructor(options) { __publicField(this, "options"); __publicField(this, "status"); __publicField(this, "wordQueue"); __publicField(this, "timer"); __publicField(this, "outputText"); __publicField(this, "isSendComplete"); __publicField(this, "generator"); __publicField(this, "$bus", createEventBus()); this.options = { ...defaultOptions, ...options }; this.status = TypeWriterStatus.PENDING; this.wordQueue = []; this.outputText = ""; this.timer = null; this.isSendComplete = false; this.generator = this.createTextGenerator(); } *createTextGenerator() { while (true) { if (this.isSendComplete) { return; } if (this.wordQueue.length === 0) { yield; continue; } const word = this.wordQueue.shift(); yield word; } } /** * 发送文本 * @param text 要发送的文本 * @returns 打字机实例 */ send(text) { if (this.isSendComplete || this.status === TypeWriterStatus.COMPLETED) { return this; } if ([void 0, null, ""].includes(text)) { return this; } this.wordQueue.push(...text.split("")); if (this.status === TypeWriterStatus.PENDING) { this.status = TypeWriterStatus.EXECUTING; this.execute(); } return this; } /** * 手动结束打字机 */ end() { this.isSendComplete = true; } /** * 手动销毁打字机 */ finish() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } this.wordQueue = []; this.generator = null; this.status = TypeWriterStatus.COMPLETED; this.emit("complete"); this.$bus.clear(); } execute() { const result = this.generator.next(); if (result.done) { this.generator = null; this.status = TypeWriterStatus.COMPLETED; this.emit("complete"); this.$bus.clear(); return; } if (result.value) { this.outputText += result.value; this.emit("change", this.outputText); } this.timer = setTimeout(() => { this.execute(); }, this.options.speed); } /** * 获取当前输出的文本 * @returns 当前输出的文本 */ getText() { return this.outputText; } emit(eventName, data) { this.$bus.emit(eventName, data); } /** * 监听事件 * @param eventName 事件名称,支持以下事件: * - 'change': 文本变化事件,当有新字符输出时触发,回调参数为当前完整文本 * - 'complete': 完成事件,当打字任务完成时触发,无回调参数 * @param callback 回调函数 * @returns 打字机实例 */ on(eventName, callback) { this.$bus.on(eventName, callback); return this; } } function createTypeWriter(options) { return new TypeWriter(options); } export { createTypeWriter };