-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtypewriter.ts
112 lines (104 loc) · 2.96 KB
/
typewriter.ts
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* INTERFACES */
interface DefaultSettings {
writeDelay: number;
deleteDelay: number;
holdOnceWritten: number;
holdOnceDeleted: number;
stopAfterOnce: boolean;
}
interface CustomSettings {
writeDelay?: number;
deleteDelay?: number;
holdOnceWritten?: number;
holdOnceDeleted?: number;
stopAfterOnce?: boolean;
}
//default settings
const typewriterSettings: DefaultSettings = {
writeDelay: 80,
deleteDelay: 40,
holdOnceWritten: 1000,
holdOnceDeleted: 300,
stopAfterOnce: false
};
class TypewriterProps {
protected settings: DefaultSettings;
protected element: HTMLElement;
protected phrases: string[];
private phrasesLength: number = 0;
protected currentPhrase: number = 0;
constructor(selector: string, phrases: string[], settings: CustomSettings) {
this.settings = { ...typewriterSettings, ...(settings || {}) };
this.element = document.querySelector(selector) as HTMLElement;
this.phrases = phrases;
this.phrasesLength = phrases.length;
}
protected updateCurrentPhrase: () => void = () => {
this.currentPhrase === this.phrasesLength - 1
? this.resetPhrases()
: this.nextPhrase();
};
private resetPhrases: () => void = () => {
this.currentPhrase = 0;
};
private nextPhrase: () => void = () => {
this.currentPhrase++;
};
}
class TypeWriter extends TypewriterProps {
constructor(
selector: string,
phrases: string[],
settings: CustomSettings = {}
) {
super(selector, phrases, settings);
this.write();
}
public write: () => void = () => {
this.element.setAttribute("placeholder", "");
this.phrases[this.currentPhrase].split("").forEach((letter, index) => {
setTimeout(() => {
this.element.setAttribute(
"placeholder",
this.element.getAttribute("placeholder") + letter
);
if (index === this.phrases[this.currentPhrase].length - 1) {
setTimeout(() => {
this.remove();
}, this.settings.holdOnceWritten);
}
}, this.settings.writeDelay * index);
});
};
protected remove: () => void = () => {
let currentWrittenPhrase: string = this.phrases[this.currentPhrase];
for (
let letterIndex = 0;
letterIndex < currentWrittenPhrase.length;
letterIndex++
) {
setTimeout(() => {
this.element.setAttribute(
"placeholder",
this.element.getAttribute("placeholder")!.slice(0, -1)
);
if (letterIndex === currentWrittenPhrase.length - 1) {
setTimeout(() => {
this.newPhrase();
}, this.settings.holdOnceDeleted);
}
}, this.settings.deleteDelay * letterIndex);
}
};
protected newPhrase: () => void = () => {
this.currentPhrase++;
if (this.currentPhrase === this.phrases.length) {
this.currentPhrase = 0;
if (this.settings.stopAfterOnce) {
this.element.setAttribute("placeholder", this.phrases[0]);
return;
}
}
this.write();
};
}