I created a unique function that both scrambles and translates text. The functionality is smooth if you patiently wait for the animation to finish before moving the mouse over to other elements. However, if you try to rush through to the next one, the previous animation abruptly stops.
const menuItems = document.querySelectorAll("#menu li"),
menuText = document.querySelectorAll("#menu li a"),
translations = document.querySelectorAll("#translation li"),
originalEnglish = [];
originalJapanese = [];
menuText.forEach((e) => {
originalEnglish.push(e.innerHTML);
});
translations.forEach((e) => {
originalJapanese.push(e.innerHTML);
});
let target;
let frame = 0;
let frame2 = 0;
let singleText;
let singleText2;
let callbackId;
const glitch = ["-", "+", "=", `[`, `;`, "#", "%", "^", "*", "_"];
let times;
let isRunning = false;
menuItems.forEach((e) => {
// });
e.addEventListener("mouseover", () => {
target = [].slice.call(menuItems).indexOf(e);
if (!menuItems[target].classList.contains("translated")) {
menuItems[target].classList.add("translated");
singleText = originalEnglish[target].split("");
times = singleText.length * 2;
frame = 0;
function glitchTranslation() {
if (frame < times + translations[target].innerHTML.length) {
if (frame < times) {
singleText[Math.floor(Math.random() * singleText.length)] = glitch[Math.floor(Math.random() * 10)];
menuText[target].innerHTML = singleText.join("");
} else {
singleText[frame - times] = translations[target].innerHTML[frame - times];
menuText[target].innerHTML = singleText.join("").slice(0, translations[target].innerHTML.length);
}
isRunning = true;
callbackId = requestAnimationFrame(glitchTranslation);
} else if (frame === times + translations[target].innerHTML.length) {
isRunning = false;
}
frame++;
}
glitchTranslation();
}
});
});
#menu {
display: flex;
flex-direction: column;
}
#menu li {
margin: 20px 0;
display: inline-block;
width: 150px;
border: 1px solid pink;
}
<header>
<nav>
<ul id="menu">
<li id="trigger1"><a href="#">something</a></li>
<li id="trigger3"><a href="#">earth</a><span class="bar"></span></li>
<li id="trigger4">
<a href="about.html">human</a><span class="bar"></span>
</li>
<li id="trigger6">
<a href="#">contact</a><span class="bar"></span>
</li>
</ul>
<ul id="translation" style="display: none">
<li>なにか</li>
<li>地球</li>
<li>人間</li>
<li>お問い合わせ</li>
</ul>
</nav>
</header>
<main></main>
<footer></footer>