-
Notifications
You must be signed in to change notification settings - Fork 23
/
typer.js
118 lines (106 loc) · 3.28 KB
/
typer.js
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
113
114
115
116
117
118
var Typer = function(element) {
this.element = element;
var delim = element.dataset.delim || ",";
var words = element.dataset.words || "override these,sample typing";
this.words = words.split(delim).filter((v) => v); // non empty words
this.delayVariance = parseInt(element.dataset.delayVariance) || 0;
this.delay = parseInt(element.dataset.delay) || 200;
this.loop = element.dataset.loop || "true";
if (this.loop === "false" ) { this.loop = 1 }
this.deleteDelay = element.dataset.deletedelay || element.dataset.deleteDelay || 800;
this.progress = { word: 0, char: 0, building: true, looped: 0 };
this.typing = true;
var colors = element.dataset.colors || "black";
this.colors = colors.split(",");
this.element.style.color = this.colors[0];
this.colorIndex = 0;
this.doTyping();
};
Typer.prototype.start = function() {
if (!this.typing) {
this.typing = true;
this.doTyping();
}
};
Typer.prototype.stop = function() {
this.typing = false;
};
Typer.prototype.doTyping = function() {
var e = this.element;
var p = this.progress;
var w = p.word;
var c = p.char;
var currentDisplay = [...this.words[w]].slice(0, c).join("");
var atWordEnd;
var timeoutDelay = ((2 * Math.random() - 1) * this.delayVariance) + this.delay;
if (this.cursor) {
this.cursor.element.style.opacity = "1";
this.cursor.on = true;
clearInterval(this.cursor.interval);
this.cursor.interval = setInterval(() => this.cursor.updateBlinkState(), 400);
}
e.innerHTML = currentDisplay;
if (p.building) {
atWordEnd = p.char === this.words[w].length;
if (atWordEnd) {
p.building = false;
} else {
p.char += 1;
}
} else {
if (p.char === 0) {
p.building = true;
p.word = (p.word + 1) % this.words.length;
this.colorIndex = (this.colorIndex + 1) % this.colors.length;
this.element.style.color = this.colors[this.colorIndex];
} else {
p.char -= 1;
}
}
if (p.word === this.words.length - 1) {
p.looped += 1;
}
if (!p.building && this.loop <= p.looped){
this.typing = false;
}
setTimeout(() => {
if (this.typing) { this.doTyping() };
}, atWordEnd ? this.deleteDelay : timeoutDelay);
};
var Cursor = function(element) {
this.element = element;
this.cursorDisplay = element.dataset.cursordisplay || element.dataset.cursorDisplay || "_";
element.innerHTML = this.cursorDisplay;
this.on = true;
element.style.transition = "all 0.1s";
this.interval = setInterval(() => this.updateBlinkState(), 400);
}
Cursor.prototype.updateBlinkState = function() {
if (this.on) {
this.element.style.opacity = "0";
this.on = false;
} else {
this.element.style.opacity = "1";
this.on = true;
}
}
function TyperSetup() {
var typers = {};
for (let e of document.getElementsByClassName("typer")) {
typers[e.id] = new Typer(e);
}
for (let e of document.getElementsByClassName("typer-stop")) {
let owner = typers[e.dataset.owner];
e.onclick = () => owner.stop();
}
for (let e of document.getElementsByClassName("typer-start")) {
let owner = typers[e.dataset.owner];
e.onclick = () => owner.start();
}
for (let e of document.getElementsByClassName("cursor")) {
let t = new Cursor(e);
t.owner = typers[e.dataset.owner];
t.owner.cursor = t;
}
}
TyperSetup();