100 lines
2.7 KiB
Vue
100 lines
2.7 KiB
Vue
<template>
|
||
<div :style="{ visibility: visibility }">
|
||
<slot></slot>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: "Writer",
|
||
props: {
|
||
// 间隔时间
|
||
interval: { type: Number, default: 75 },
|
||
// 光标 建议有表格的时候不要使用光标 会导致渲染异常
|
||
cursorStr: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
visibility: "hidden", //
|
||
timer: 0, // 定时器
|
||
initialDom: null, // 记录初始dom
|
||
progress: 0, // 当前文本书写进度
|
||
// writeStatus: "NotStart",// 当前书写状态=> NotStart: 未开始;Processing:书写中;Completed 书写完毕
|
||
};
|
||
},
|
||
mounted() {
|
||
// 拷贝初始所有dom 便于重新开始
|
||
this.initialDom = JSON.parse(JSON.stringify(this.$el.innerHTML));
|
||
this.start();
|
||
},
|
||
methods: {
|
||
// 开始 / 重新开始
|
||
start() {
|
||
this.visibility = "visible";
|
||
this.progress = 0;
|
||
this.$el.innerHTML = "";
|
||
clearInterval(this.timer);
|
||
this.write();
|
||
this.$emit("writeStart");
|
||
},
|
||
// 暂停
|
||
pause() {
|
||
clearInterval(this.timer);
|
||
this.$emit("writePause");
|
||
},
|
||
// 继续
|
||
continueWrite() {
|
||
if(!this.progress || this.progress >= this.initialDom.length){
|
||
return
|
||
}
|
||
clearInterval(this.timer);
|
||
this.write();
|
||
this.$emit("writeContinue");
|
||
},
|
||
// 重置
|
||
reset() {
|
||
this.visibility = "hidden";
|
||
this.progress = 0;
|
||
this.$el.innerHTML = "";
|
||
clearInterval(this.timer);
|
||
},
|
||
// 书写
|
||
write() {
|
||
this.timer = setInterval(() => {
|
||
var current = this.initialDom.substr(this.progress, 1);
|
||
// console.log(current);
|
||
// 跳过 标签渲染
|
||
if (current === "<") {
|
||
this.progress = this.initialDom.indexOf(">", this.progress) + 1;
|
||
} else {
|
||
this.progress++;
|
||
}
|
||
// console.log(this.progress & 1, "this.progress");
|
||
// 如果有光标配置 拼接到最新渲染的地方
|
||
if (this.cursorStr) {
|
||
this.$el.innerHTML =
|
||
this.initialDom.substring(0, this.progress) +
|
||
(this.progress < this.initialDom.length && this.progress & 1
|
||
? this.cursorStr
|
||
: "");
|
||
} else {
|
||
this.$el.innerHTML = this.initialDom.substring(0, this.progress);
|
||
}
|
||
// 文本书写进度 大于需要书写的总长度 判断为渲染完成
|
||
if (this.progress >= this.initialDom.length) {
|
||
clearInterval(this.timer);
|
||
this.$emit("writeEnd"); // 打字完成后的回调方法
|
||
}
|
||
this.$emit("writeIsWrite");
|
||
}, this.interval);
|
||
},
|
||
},
|
||
beforeDestroy() {
|
||
clearInterval(this.timer);
|
||
},
|
||
};
|
||
</script>
|