Skip to content

Instantly share code, notes, and snippets.

@anargu
Last active March 23, 2021 21:49
Show Gist options
  • Save anargu/1ae6ae0c2f9fed1344f89d164369e761 to your computer and use it in GitHub Desktop.
Save anargu/1ae6ae0c2f9fed1344f89d164369e761 to your computer and use it in GitHub Desktop.
Text Effect for a title in HTML
!function(e){"undefined"==typeof module?this.charming=e:module.exports=e}(function(e,n){"use strict";n=n||{};var t=n.tagName||"span",o=null!=n.classPrefix?n.classPrefix:"char",r=1,a=function(e){for(var n=e.parentNode,a=e.nodeValue,c=a.length,l=-1;++l<c;){var d=document.createElement(t);o&&(d.className=o+r,r++),d.appendChild(document.createTextNode(a[l])),n.insertBefore(d,e)}n.removeChild(e)};return function c(e){for(var n=[].slice.call(e.childNodes),t=n.length,o=-1;++o<t;)c(n[o]);e.nodeType===Node.TEXT_NODE&&a(e)}(e),e});
<script src="./charming.min.js"></script>
<script>
// Gets a random integer.
const getRandomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
// Equation of a line (y = mx + b ).
const lineEq = (y2, y1, x2, x1, currentVal) => {
const m = (y2 - y1) / (x2 - x1);
const b = y1 - m * x1;
return m * currentVal + b;
};
// Some random chars.
const chars = ['$','%','#','&','=','*','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','.',':',',','^'];
const charsTotal = chars.length;
export class TextEffect {
constructor(selector) {
this.el = document.querySelector(selector)
charming(this.el)
this.letters = Array.from(this.el.querySelectorAll('span')).sort(() => 0.5 - Math.random())
this.letters.forEach(letter => letter.dataset.initial = letter.innerHTML);
}
animate(loop = true) {
randomizeLetters(this.letters)
if (loop) {
setInterval(() => {
randomizeLetters(this.letters)
}, 2000);
}
}
}
// Randomize letters function. Used when navigating the slideshow to switch the curretn slide´s texts.
export const randomizeLetters = (letters) => {
return new Promise((resolve, reject) => {
const lettersTotal = letters.length;
let cnt = 0;
letters.forEach((letter, pos) => {
let loopTimeout;
const loop = () => {
letter.innerHTML = chars[getRandomInt(0,charsTotal-1)];
loopTimeout = setTimeout(loop, getRandomInt(50,500));
};
loop();
const timeout = setTimeout(() => {
clearTimeout(loopTimeout);
letter.style.opacity = 1;
letter.innerHTML = letter.dataset.initial;
++cnt;
if ( cnt === lettersTotal ) {
resolve();
}
}, pos*lineEq(40,0,8,200,lettersTotal));
});
});
};
// Here select the id of the title element and animate the title after 1000 milliseconds (1 second)
const regoshTitleEl = new TextEffect('#front-title')
setTimeout(() => {
regoshTitleEl.animate()
}, 1000)
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment