-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypewriterComponent.vue
More file actions
96 lines (80 loc) · 2.34 KB
/
TypewriterComponent.vue
File metadata and controls
96 lines (80 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<template>
<span>
<span v-if="currentText">{{ currentText }}</span>
<span v-else> </span>
<span v-if="showCursor" class="cursor">|</span>
</span>
</template>
<script setup>
/* Super easy, drop in TypeWriter Component for Vue 3
*
* Just use like this <TypeWriter :texts="['TEXT1', 'TEXT2']" :eraseDelay="100" :typeDelay="100" :waitTimer="1800" /> */
import { ref, watch, onMounted, defineProps } from "vue";
const props = defineProps(["texts", "eraseDelay", "typeDelay", "waitTimer"]);
const texts = ref(props.texts || []);
const currentIndex = ref(0);
const currentText = ref("");
const showCursor = ref(true); // enable / disable cursor -> could pass this to props aswell if you need it
//start typing
const startTyping = () => {
// loop through texts
if (currentIndex.value < texts.value.length) {
const text = texts.value[currentIndex.value]; //get the text of this element
let index = 0; // i for looping through the word character by character
const typingInterval = setInterval(() => {
// typing interval
currentText.value = text.slice(0, index);
index++;
if (index > text.length) {
clearInterval(typingInterval);
setTimeout(() => {
startErasing();
}, props.waitTimer || 100); // use timer from props or 100
}
}, props.typeDelay || 100); // same here
}
if (currentIndex.value == texts.value.length) {
currentIndex.value = 0; // reset the index
startTyping(); // start again after array is empty
}
};
const startErasing = () => {
const text = texts.value[currentIndex.value];
let index = text.length;
const erasingInterval = setInterval(() => {
currentText.value = text.slice(0, index);
index--; // same principle but opposite
if (index < 0) {
clearInterval(erasingInterval);
showCursor.value = false; // simulate a blinking cursor
setTimeout(() => {
currentIndex.value++;
currentText.value = "";
showCursor.value = true;
startTyping();
}, props.eraseDelay || 100);
}
}, props.eraseDelay || 100);
};
watch(texts, () => {
currentIndex.value = 0;
startTyping();
});
onMounted(() => {
startTyping();
});
</script>
<style scoped>
.cursor {
animation: blink 0.7s infinite;
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
</style>