Сообщение от Perepelenok
|
как реализовать такой эффект перебора текста пунктов меню при наведении, как на этом сайте https://fabianirsara.com/ ?
|
При взаимодействии с кнопкой запускать функцию, которая берёт исходное слово и меняет местами его случайно взятые буквы несколько раз. После каждого изменения слова надо показывать в кнопке изменённое слово. Получается анимация! Только затем нужно сразу проиграть её задом наперёд, чтобы всё вернулось на место!
Пример...
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
html {
background: #1e1e20;
}
.roll-text {
all: unset;
color: white;
font: bold 250% monospace;
border-bottom: medium solid;
padding: .25em;
margin: .25em;
transition: 500ms;
}
.roll-text:hover { color: bisque; }
.roll-text:focus { color: gold; }
</style>
</head>
<body>
<a href="#" class="roll-text">Hello</a>
<button class="roll-text">Codepen</button>
<button class="roll-text">Rolling Text</button>
<script>
{
const isRolling = Symbol("rolling text");
function getPositions(length) {
return Array.from(new Array(length), () => [
(length * Math.random() | 0) % length,
(length * Math.random() | 0) % length,
]);
}
async function rollText(element) {
if(element[isRolling]) return;
element[isRolling] = true;
const word = [...element.textContent];
const ps = getPositions(word.length);
const computedWords = [word.join("")];
for(const [p1, p2] of ps) {
[word[p1], word[p2]] = [word[p2], word[p1]];
computedWords.push(element.textContent = word.join(""));
await delay(30);
}
while(computedWords.length) {
const word = computedWords.pop();
element.textContent = word;
await delay(30);
}
element[isRolling] = false;
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function rollHandler({ target }) {
if(target.matches(".roll-text"))
rollText(target);
}
addEventListener("pointerover", rollHandler);
addEventListener("pointerout", rollHandler);
}
</script>
</body>
</html>