Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

Произвольное появление букв

#javascript #css


Есть задача. Появления текста в блоке, в произвольной последовательности, по буквам
(Например для слова Hello, чтоб буквы появлялись в подобной последовательности eHlol).
Тестовый блок

Hello,
Javascript is an awesome language
Единственное что пришло в голову, это обернуть каждую букву текста в и потом показывать его с рандомный таймаутом. Но сложность обстоит с тэгами. Что с ними можно сделать? Убирать, оборачивать потом снова добавлять? Может быть это реализуется без JS с помощью СSS?


Ответы

Ответ 1



Пока другого не придумал. Каждую букву обернуть в span с классом, который ставит visibility: hidden, одновременно запихнув все созданные span'ы в массив. Массив случайно перемешать. И затем по очереди у каждого из массива снимать прячущий класс: var spans = [] ,allTextNodes = getTextNodes( document.getElementById('b-test')) ,i ,timer ; /** * recursively get all text nodes as an array for a given element */ function getTextNodes(node) { var childTextNodes = []; if (!node.hasChildNodes()) return; var childNodes = node.childNodes; for (var i = 0; i < childNodes.length; i++) { if (childNodes[i].nodeType == Node.TEXT_NODE) { childTextNodes.push(childNodes[i]); } else if (childNodes[i].nodeType == Node.ELEMENT_NODE) { Array.prototype.push.apply(childTextNodes, getTextNodes(childNodes[i])); } } return childTextNodes; } /** * given a text node, wrap each character in the * given tag. */ function wrapEachCharacter(textNode, tag, className = '') { var text = textNode.nodeValue; var parent = textNode.parentNode; var characters = text.split(''); var elements = []; characters.forEach(function(character) { var element = document.createElement(tag); element.className = className; var characterNode = document.createTextNode(character); element.appendChild(characterNode); parent.insertBefore(element, textNode); spans.push(element); }); parent.removeChild(textNode); } allTextNodes.forEach(function(textNode) { wrapEachCharacter(textNode, 'span', 'h'); }); /** * Shuffles array in place. * @param {Array} a items The array containing the items. */ function shuffle(a) { var j, x, i; for (i = a.length; i; i--) { j = Math.floor(Math.random() * i); x = a[i - 1]; a[i - 1] = a[j]; a[j] = x; } } shuffle(spans); i = spans.length - 1; function showOne() { spans[i--].className = ""; if (i < 0) clearInterval(timer); } timer = window.setInterval(showOne.bind(this), 100); span.h{visibility: hidden}
Hello,
Javascript is an awesome language
Что улучшить: пробелы не надо оборачивать и прятать – только видимые буквы, иначе нарушается видимый «ритм» появления символов. Ещё недостаток: слова перестают быть целыми словами и могут рваться переносом строки. Выход: оборачивать каждое слово в .

Ответ 2



Спасибо! Пока ждал ответа, сам набросал, но ваш вариант мне нравится больше) В процессе столкнулся еще с одним моментом. Слова больше не являются словами и переносы строк могут сыграть злую шутку. Думаю правильно будет оборачивать слова перед обработкой в отдельные контейнеры которые будут виртуальными словами. $(function() { $('.random-fading').each(function() { var input = $(this).html(); var charRegexp = /<[^>]*>/g; var wordRegexp = /\S+/g; var match; var offset = 1; var replacer = []; var wordReplacer = []; var output = '
'; while ((match = charRegexp.exec(input)) != null) { replacer[match.index - offset] = match[0]; offset += match[0].length; } input = input.replace(charRegexp, ''); offset = 1; while ((match = wordRegexp.exec(input)) != null) { wordReplacer[match.index - offset] = true; offset += 14; //console.log(match[0]); } input.split('').forEach(function(value, key) { if (/^\S$/.exec(value)) { output += '' + value + ''; } else { //пустые символы не оборачиваем output += value; } if (wordReplacer[key] && key != 0) { output += ''; } if (replacer[key]) { //добавить тег output += replacer[key]; } }); //console.log(output); output += ''; $(this).html(output); }); $('.random-fading span.h').each(function() { var self = $(this); setTimeout(function() { self.removeClass('h'); }, Math.floor((Math.random() * 300) + 100)); }); }); .random-fading span.h { opacity: 0; transition: 1s linear all; }
Hello,
Javascript is an awesome language
ОченьДлинныйТекст КоторыйДолженПереноситсяПоСловам, ПростаяПроверкаНаВсякийСлучайАТоМалоЛиЧтоТоПойдётНеТак:-(((((


Комментариев нет:

Отправить комментарий