示意图
代码如下:打字效果,支持vue2或者vue3
<template>
<view class="typerw">
<text id="typewriter-cont">{{content}}</text>
<text v-if="!item.select" class="w_gb">|</text>
</view>
</template>
<script>
export default {
name: "lj-typewriter",
props: {
fontSize: {
type: Number,
default: 36
},
fontColor: {
type: String,
default: '#000'
},
textValue: {
type: String
},
time: { // 每个字符显示的时间
type: Number,
default: 25
},
direction: { // 方向
type: Boolean,
default: true
},
item: {
type: Object,
default: function() {
return {
time: '',
icon: '',
name: '',
content: '',
isMe: false
}
}
}
},
watch: {
textValue: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.showText();
}
},
},
},
data() {
return {
content: '',
isAnimating: false,
timers: []
};
},
methods: {
showText() {
// 清除之前的定时器
this.clearTimers();
if (this.item.select) {
// 如果文本已经显示过,直接设置content
this.content = this.textValue;
this.isAnimating = false;
} else {
this.isAnimating = true;
const totalLength = this.textValue.length;
if (this.direction) {
for (let n = 1; n <= totalLength; n++) {
const timer = setTimeout(() => {
console.log(this.textValue, '-this.textValue')
this.content = this.textValue.substr(0, n);
if (n === totalLength) {
this.isAnimating = false;
this.item.select = true
}
}, (n - 1) * this.time);
this.timers.push(timer);
}
} else {
for (let n = totalLength; n >= 0; n--) {
const timer = setTimeout(() => {
this.content = this.textValue.substr(0, n);
if (n === 0) {
this.isAnimating = false;
this.item.select = true
}
}, (totalLength - n) * this.time);
this.timers.push(timer);
}
}
}
},
clearTimers() {
this.timers.forEach(timer => clearTimeout(timer));
this.timers = [];
this.isAnimating = false;
}
},
mounted() {
this.showText();
},
beforeDestroy() {
this.clearTimers();
}
}
</script>
<style scoped lang="scss">
.typerw {
.w_gb {
margin-left: 5px;
animation: flash 0.8s linear infinite;
color: #000;
}
}
@keyframes flash {
0% {
opacity: 1;
}
50% {
opacity: 0.0;
}
100% {
opacity: 1;
}
}
</style>