A little text decoding / scramble effect
A Pen by Justin Windle on CodePen.
| <div class="container"> | |
| <div class="text"></div> | |
| </div> |
| // —————————————————————————————————————————————————— | |
| // 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 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 = () => { | |
| fx.setText(phrases[counter]).then(() => { | |
| setTimeout(next, 800) | |
| }) | |
| counter = (counter + 1) % phrases.length | |
| } | |
| next() |
| @import 'https://fonts.googleapis.com/css?family=Roboto+Mono:100' | |
| html, body | |
| font-family 'Roboto Mono', monospace | |
| background #212121 | |
| height 100% | |
| .container | |
| height 100% | |
| width 100% | |
| justify-content center | |
| align-items center | |
| display flex | |
| .text | |
| font-weight 100 | |
| font-size 28px | |
| color #FAFAFA | |
| .dud | |
| color #757575 |
A little text decoding / scramble effect
A Pen by Justin Windle on CodePen.