Skip to content

Instantly share code, notes, and snippets.

@breaker84
Created March 4, 2023 22:25
Show Gist options
  • Save breaker84/1b0cd76beca4ec0be3c4104381a12ad6 to your computer and use it in GitHub Desktop.
Save breaker84/1b0cd76beca4ec0be3c4104381a12ad6 to your computer and use it in GitHub Desktop.
Decode Text Effect

Decode Text Effect

Text that appears to "decode" as if the characters where encrypted.

4 states per letter: Transparent/Line/Block/Visible. These states are shuffled for a unique "decode" effect each time.

A Pen by breaker84 on CodePen.

License.

<div class="decode-text">
<div class="text-animation">R</div>
<div class="text-animation">a</div>
<div class="text-animation">n</div>
<div class="text-animation">d</div>
<div class="text-animation">o</div>
<div class="text-animation">m</div>
<div class="text-animation">i</div>
<div class="text-animation">z</div>
<div class="text-animation">e</div>
<div class="text-animation">d</div>
<div class="space"></div>
<div class="text-animation">d</div>
<div class="text-animation">e</div>
<div class="text-animation">c</div>
<div class="text-animation">o</div>
<div class="text-animation">d</div>
<div class="text-animation">e</div>
<div class="space"></div>
<div class="text-animation">e</div>
<div class="text-animation">f</div>
<div class="text-animation">f</div>
<div class="text-animation">e</div>
<div class="text-animation">c</div>
<div class="text-animation">t</div>
</div>
<a id="refresh" onclick="decodeText();">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
</a>
/* ------------------------------------------------------------------------ *
4 states per letter: Transparent | Line | Block | Visible.
These states are shuffled for a unique "decode" effect each time.
* ------------------------------------------------------------------------ */
function decodeText(){
var text = document.getElementsByClassName('decode-text')[0];
// debug with
// console.log(text, text.children.length);
// assign the placeholder array its places
var state = [];
for(var i = 0, j = text.children.length; i < j; i++ ){
text.children[i].classList.remove('state-1','state-2','state-3');
state[i] = i;
}
// shuffle the array to get new sequences each time
var shuffled = shuffle(state);
for(var i = 0, j = shuffled.length; i < j; i++ ){
var child = text.children[shuffled[i]];
classes = child.classList;
// fire the first one at random times
var state1Time = Math.round( Math.random() * (2000 - 300) ) + 50;
if(classes.contains('text-animation')){
setTimeout(firstStages.bind(null, child), state1Time);
}
}
}
// send the node for later .state changes
function firstStages(child){
if( child.classList.contains('state-2') ){
child.classList.add('state-3');
} else if( child.classList.contains('state-1') ){
child.classList.add('state-2')
} else if( !child.classList.contains('state-1') ){
child.classList.add('state-1');
setTimeout(secondStages.bind(null, child), 100);
}
}
function secondStages(child){
if( child.classList.contains('state-1') ){
child.classList.add('state-2')
setTimeout(thirdStages.bind(null, child), 100);
}
else if( !child.classList.contains('state-1') )
{
child.classList.add('state-1')
}
}
function thirdStages(child){
if( child.classList.contains('state-2') ){
child.classList.add('state-3')
}
}
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
// Demo only stuff
decodeText();
// beware: refresh button can overlap this timer and cause state mixups
setInterval(function(){ decodeText(); }, 10000);
.decode-text {
width: 100%;
font-size: 30px;
text-align: center;
}
.space {
display: inline-block;
width: 10px;
}
.text-animation {
display: inline-block;
position: relative;
color: transparent;
text-transform: uppercase;
&:before {
content: "";
color: black;
position: absolute;
top: 50%;
left: 50%;
background: #0e182d;
width: 0;
height: 1.2em;
-webkit-transform: translate(-50%, -55%);
-ms-transform: translate(-50%, -55%);
transform: translate(-50%, -55%);
}
&.state-1 {
&:before {
width: 1px;
}
}
&.state-2 {
&:before {
width: 0.9em;
}
}
&.state-3 {
color: black;
&:before {
width: 0;
}
}
}
// demo styles
#refresh {
position: absolute;
top: 20px;
left: 20px;
cursor: pointer;
}
@import url(https://fonts.googleapis.com/css?family=Share+Tech+Mono);
div {
font-family: "Share Tech Mono", monospace;
}
body {
height: 100vh;
align-items: center;
display: flex;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment