Skip to content

Instantly share code, notes, and snippets.

@puccaso
Forked from anonymous/index.html
Created August 30, 2017 22:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save puccaso/e9b23d676c39b9724e4bf4c2dabdb234 to your computer and use it in GitHub Desktop.
Save puccaso/e9b23d676c39b9724e4bf4c2dabdb234 to your computer and use it in GitHub Desktop.
Text Scramble Effect
<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 = [
'sıfat,',
'Aynı düşüncede',
'aynı görüşte olan',
'düşündeş',
'mutabık',
'he\'mfikir',
'oydaş',
'#hemfikir',
'#hemfikir.com'
]
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment