We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Adworse Codes HereProgrammer's travelogue |
|||
by Dima Ermilov | Tagged: tricks, js |
JS Typewriter
When designing this blog, I was thinking about making it more typewriter-like. At the end of the day, I decided to use an exceptionally well made dynamic font (its story is a great story on its own). But my first idea was to emulate a typewriter by graceful destruction of this very JetBrains Mono typeface.
I thought of moving every letter on a small amount in vertical and horizontal directions and (counter)clockwise. A little blur would also help. These amounts should’ve been random for the entire text, but consistent for any specific letter. At first, I planned to generate a map of random parameters for every symbol present in the transformed test, but this just looked boring.
And please remind me to tell the story of the Knuth-recommended magic constant 0x9e3779b9
if I forget to do so :)
Here’s the complete (smelly) code:
const __properHash = (str) => {
res = (
(Math.imul(
str.split("").reduce((acc, symbol) => acc + symbol.charCodeAt(0), 0),
0x9e3779b9,
) >>> 25) - 2**6
);
return res;
};
const __wrapWord = (word) => {
wrapped = word
.split("")
.map(
(char) =>
`<span style="transform:rotate(${
__properHash("til" + char) / 2**4
}deg); filter:blur(${
0.45 + (Math.abs(__properHash("blur" + char)) / 2**8)
}px); translate: ${2 + __properHash("move" + char) / 2**6}% ${
__properHash("jump" + char) / 2**4
}%; margin-top: 0; display:inline-block">${char}</span>`,
);
return ['<span style="white-space:nowrap">', wrapped, "</span>"]
.flat()
.join("");
};
const __typewriter = () => {
document.querySelectorAll("typewriter").forEach((node) => {
node.innerHTML = node.innerHTML
.split(/\s/)
.map(__wrapWord)
.flat()
.join(" ");
});
};