You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.4 KiB
JavaScript
76 lines
2.4 KiB
JavaScript
4 years ago
|
// TextScramble
|
||
|
class TextScramble {
|
||
|
constructor(el) {
|
||
|
this.el = el
|
||
|
this.chars = '!<>-_\\/[]{}—=+*^?#________'
|
||
|
this.update = this.update.bind(this)
|
||
|
}
|
||
|
|
||
|
setText(newText) {
|
||
|
const oldText = this.el.innerText
|
||
|
const length = Math.max(oldText.length, newText.length)
|
||
|
const promise = new Promise((resolve) => this.resolve = resolve)
|
||
|
this.queue = []
|
||
|
for (let i = 0; i < length; i++) {
|
||
|
const from = oldText[i] || ''
|
||
|
const to = newText[i] || ''
|
||
|
const start = Math.floor(Math.random() * 40)
|
||
|
const end = start + Math.floor(Math.random() * 40)
|
||
|
this.queue.push({from, to, start, end})
|
||
|
}
|
||
|
cancelAnimationFrame(this.frameRequest)
|
||
|
this.frame = 0
|
||
|
this.update()
|
||
|
return promise
|
||
|
}
|
||
|
|
||
|
update() {
|
||
|
let output = ''
|
||
|
let complete = 0
|
||
|
for (let i = 0, n = this.queue.length; i < n; i++) {
|
||
|
let {from, to, start, end, char} = this.queue[i]
|
||
|
if (this.frame >= end) {
|
||
|
complete++
|
||
|
output += to
|
||
|
} else if (this.frame >= start) {
|
||
|
if (!char || Math.random() < 0.28) {
|
||
|
char = this.randomChar()
|
||
|
this.queue[i].char = char
|
||
|
}
|
||
|
output += `<span class="dud">${char}</span>`
|
||
|
} else {
|
||
|
output += from
|
||
|
}
|
||
|
}
|
||
|
this.el.innerHTML = output
|
||
|
if (complete === this.queue.length) {
|
||
|
this.resolve()
|
||
|
} else {
|
||
|
this.frameRequest = requestAnimationFrame(this.update)
|
||
|
this.frame++
|
||
|
}
|
||
|
}
|
||
|
|
||
|
randomChar() {
|
||
|
return this.chars[Math.floor(Math.random() * this.chars.length)]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const phrases = [
|
||
|
"Hey!",
|
||
|
"That's my page!",
|
||
|
"if you like", "check out", "my social media", "below :D"
|
||
|
]
|
||
|
|
||
|
const el = document.querySelector('.text')
|
||
|
const fx = new TextScramble(el)
|
||
|
|
||
|
let counter = 0
|
||
|
const next = () => {
|
||
|
fx.setText(phrases[counter]).then(() => {
|
||
|
setTimeout(next, 600)
|
||
|
})
|
||
|
counter = (counter + 1) % phrases.length
|
||
|
}
|
||
|
|
||
|
next()
|