-
Notifications
You must be signed in to change notification settings - Fork 0
/
ticker.js
90 lines (71 loc) · 2.7 KB
/
ticker.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
export default function ticker(wrapperID, opts) {
const defaultOptions = {
uppercase: true,
extra: ",.:+=/()-?",
speed: 30,
wait: 5500,
};
const options = { ...defaultOptions, ...opts };
const alph = `01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ${
!options.uppercase ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toLowerCase() : ""
}${options.extra} `;
const wrapper = document.getElementById(wrapperID);
let k = 1;
// len represents the longest length of any word, which will determine the final array length
let len = 0;
// HTMLCollection is not an array, more like arraylike
const elems = Array.from(wrapper.children);
const alphChars = alph.split("");
// receives array wordChars, returns array filled with extra spaces
function fill(wordChars) {
while (wordChars.length < len) {
wordChars.push(" ");
}
return wordChars;
}
const texts = elems.map((elem) => {
const text = elem.textContent;
len = Math.max(len, text.length);
return options.uppercase ? text.toUpperCase() : text;
});
const target = document.createElement("div");
// creates a succession of spans with charcters, requires an array to form a word with spans.
function render(chars) {
target.data = {};
target.data.prev = chars.join("");
fill(chars);
const newChars = chars.map((char) => (char === " " ? " " : char));
return `<span>${newChars.join("</span><span>")}</span>`;
}
console.log(texts);
wrapper.innerHTML = render(texts[0].split(""));
setInterval(() => {
const nextWordChars = fill(texts[k].split(""));
// ['✈', ' ', 'Z', 'X', 'Y', ' ', ' ', ' ', ' ', ' ', ' ', ' '] <= next would be the next word
const prevWordChars = fill(target.data.prev.split(""));
// ['✈', ' ', 'A', 'B', 'C', ' ', ' ', ' ', ' ', ' ', ' ', ' '] <= prev would be the prev word
const chars = prevWordChars;
nextWordChars.forEach((nextWordChar, i) => {
if (nextWordChar === prevWordChars[i]) {
return;
}
// index is the location where the char from the prevWord which is evaluated at hand
let index = alph.indexOf(prevWordChars[i]);
let j = 0;
const step = () => {
let isRequest = true;
if (nextWordChar !== alphChars[index]) {
// go to next char in the alphChars array, unless you reached the last in which case go to 0
index = index === alphChars.length - 1 ? 0 : index + 1;
} else {
isRequest = false;
}
chars[i] = alphChars[index];
wrapper.innerHTML = render(chars);
isRequest && window.requestAnimationFrame(step);
};
window.requestAnimationFrame(step);
});
k = k == texts.length - 1 ? 0 : k + 1;
}, options.wait);
}