Text scramble animation/effect
A Pen by Shane White on CodePen.
<div class="text-change-container"> | |
<div class="text-change"></div> | |
</div> | |
<div class="text-change-container"> | |
<div class="text-change"></div> | |
</div> |
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 = [ | |
"Shane White", | |
"cqrCyber / cc", | |
"tools related to Cyber", | |
"Security", | |
"&", | |
"Computer / Science", | |
"&", | |
"Ethical Hacking { * }", | |
"an initiative to help secure the Cyber", | |
"https://godiam.sharepoint.com", | |
"entwicklerprogramm@pm.me", | |
"", | |
"", | |
"" | |
]; | |
const el = document.querySelector(".text-change"); | |
const fx = new TextScramble(el); | |
let counter = 0; | |
const next = () => { | |
fx.setText(phrases[counter]).then(() => { | |
setTimeout(next, 2000); | |
}); | |
counter = (counter + 1) % phrases.length; | |
}; | |
next(); |
@import 'https://fonts.googleapis.com/css2?family=Goldman&display=swap' | |
html, body | |
background: #0D0D0D | |
height: 100% | |
.text-change-container | |
height: 100% | |
width: 100% | |
justify-content: center | |
align-items: center | |
display: flex | |
.text-change | |
font-family: 'Goldman', monospace | |
font-weight: normal | |
font-size: larger | |
color: rgba(200, 200, 200, 1) | |
filter: drop-shadow(0 0 0.3em rgba(200, 200, 200, 0.3)) | |
.dud | |
color: rgba(242, 5, 5, 0.8) | |
filter: drop-shadow(0 0 0.5em red) | |
/* Color Theme Swatches in Hex */ | |
.Abstract-1-hex | |
color: #F2F2F2 | |
.Abstract-2-hex | |
color: #BDB8D9 | |
.Abstract-3-hex | |
color: #010D00 | |
.Abstract-4-hex | |
color: #D7D9C7 | |
.Abstract-5-hex | |
color: #0D0D0D | |
/* Color Theme Swatches in RGBA */ | |
.Abstract-1-rgba | |
color: rgba(242, 242, 242, 1) | |
.Abstract-2-rgba | |
color: rgba(189, 184, 217, 1) | |
.Abstract-3-rgba | |
color: rgba(1, 13, 0, 1) | |
.Abstract-4-rgba | |
color: rgba(215, 217, 199, 1) | |
.Abstract-5-rgba | |
color: rgba(13, 13, 13, 1) | |
/* Color Theme Swatches in HSLA */ | |
.Abstract-1-hsla | |
color: hsla(0, 0, 94, 1) | |
.Abstract-2-hsla | |
color: hsla(249, 30, 78, 1) | |
.Abstract-3-hsla | |
color: hsla(115, 100, 2, 1) | |
.Abstract-4-hsla | |
color: hsla(66, 19, 81, 1) | |
.Abstract-5-hsla | |
color: hsla(0, 0, 5, 1) |
Text scramble animation/effect
A Pen by Shane White on CodePen.