Created
November 3, 2017 22:06
-
-
Save adiog/cc3f642a3d7d4e39c5b3762972cee3d7 to your computer and use it in GitHub Desktop.
neo-text-scramble.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title></title> | |
<script> | |
// —————————————————————————————————————————————————— | |
// 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)]; | |
} | |
} | |
// —————————————————————————————————————————————————— | |
// Example | |
// —————————————————————————————————————————————————— | |
const bootstrap = function() { | |
const phrases = [ | |
'Neo,', | |
'sooner or later', | |
'you\'re going to realize', | |
'just as I did', | |
'that there\'s a difference', | |
'between knowing the path', | |
'and walking the path' | |
]; | |
const el = document.querySelector('.text'); | |
const fx = new TextScramble(el); | |
let counter = 0; | |
const next = function () { | |
fx.setText(phrases[counter]).then(() => { | |
setTimeout(next, 800) | |
}); | |
counter = (counter + 1) % phrases.length; | |
}; | |
next(); | |
} | |
</script> | |
</head> | |
<body onload="bootstrap();"> | |
<div class="container"> | |
<div class="text"></div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment