Показать сообщение отдельно
  #2 (permalink)  
Старый 17.01.2019, 09:23
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от 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&nbsp;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>
Ответить с цитированием