С помощью эффектов и анимации текста можно сделать занимательные веб-страницы, и в этом уроке мы рассмотрим один из таких эффектов, а именно, разберем, как сделать печатающийся текст с помощью JavaScript.
Опубликовал: | Paul.Z |
Автор: | Paul Z |
Опубликовано: | 11.06.2020 |
Просмотров: | 11156 |
Рейтинг: |
Самонабирающийся текст нередко можно встретить в сценах фантастического кино в жанре киберпанк. Первое, что всплывает в памяти, фильм "Матрица" и сцена, когда Тринити посылает сообщение Нео, печатающееся на экране его монитора.
Cцена из кинофильма «Матрица» с печатающимся текстом.
Что ж, эту сцену можно взять за основу нашего будущего текстового эффекта для веб-страницы. Таким образом, конечный результат будет выглядеть вот так.
Эффект печатающегося текста в стиле сцены из «Матрицы» с помощью JavaScript.
Для начала выберите текст, который вам нравится. Я выбрал цитату из «Матрицы». Его следует поместить в блок, с которым затем можно будет взаимодействовать.
<div class="screen"> Wake up, Neo... The Matrix has you... Follow the white rabbit... Knock knock, Neo. </div>
Далее, конечно же, понадобиться стилизовать печатающийся текст в соответствие сцене в кино, поэтому добавим для него некоторые стили.
.screen { max-width: 500px; font: 16px/140% 'Courier New', Courier, Arial; padding: 20px; background: black; color: lime; white-space: pre-wrap; } .screen span { visibility: hidden; } .screen span.visible { visibility: visible; } .screen span.cursor { background: lime; animation: blinking 0.5s step-start infinite; } @keyframes blinking { 50% {opacity: 1;} 100% {opacity: 0;} }
Для блока с текстом назначим класс .screen
и установим для него черный цвет фона background: black;
. Это будет экран. Для текста установим цвет lime (светло-зеленый).
Затем надо написать несколько свойств для элемента span и добавить к нему пару классов. Когда приступим к разбору скрипта печатающего текст, вы поймете, зачем они нужны.
Для класса .cursor
добавим цвет фона lime и применим к нему анимацию, ключи которой бесконечно (infinite) и поочередно меняют прозрачность элемента с данным классом. Как можно догадаться из названия класса, это будет мигающий курсор самонабирающегося текста.
Для анимации курсора (blinking) нужно установить функцию времени step-start, чтобы CSS-свойства ключей анимации применялись сразу, а не плавно.
Помимо всего прочего, я задал тексту свойство white-space: pre-wrap;
, поскольку самонабирающийся текст должен выводиться построчно. Но это совершенно не обязательно, если форматирование не важно.
Теперь займемся самим эффектом печатающегося текста, а для этого воспользуемся возможностями JavaScript. Ниже представлен весь код, а еще ниже детально разберем его работу.
let textBox = document.querySelector('.screen'), text = textBox.innerText, newHTML = ''; for(i = 0; i < text.length; i++){ newHTML += '<span>'+text[i]+'<span>'; } textBox.innerHTML = newHTML; let spans = textBox.querySelectorAll('span'), count = 0, timeout = 0; function typing_text(){ spans[count].classList.add('visible'); if(spans[count].innerText == ' ' || spans[count].innerHTML == ' '){ timeout = Math.floor(Math.random() * Math.floor(1000)); spans[count].classList.add('cursor'); }else{ timeout = 50; } if (count < text.length - 1){ setTimeout(() => { spans[count].classList.remove('cursor'); count ++; typing_text(); }, timeout); } } typing_text();
И так, давайте теперь разберемся, что и как работает.
JavaScript предлагает хорошие возможности для работы с текстом, предоставляя доступ к каждому символу строки, как к элементу массива. Этим мы и воспользуемся, но прежде всего, нужно получить элемент блока с текстом (textBox), взять из него текст (text) и провести кое-какую манипуляцию с ним, результат которой мы помести в переменную newHTML.
let textBox = document.querySelector('.screen'), text = textBox.innerText, newHTML = '';
Вся манипуляция будет заключаться в том, что каждый символ нашего текста должен стать заключенным в теги <span>...<span>
. Это позволит поочередно применять к каждому последующему тегу с символом с определенной задержкой стилистическое свойство, что будет выглядеть, как печатающийся текст. Этим стилистическим свойством является visibility: visible;
, которое будет присваиваться тегам span при добавлении класса .visible
. Это свойство удобно тем, что просто скрывает элементы, то есть, наш текст, не изменяя при этом размеров родительского блока. Вот почему всем тегам span мы задали по умолчанию visibility: hidden;
, ну а следующий цикл просто «оденет» каждый символ текста в этот тег и, таким образом, спрячет его.
for(i = 0; i < text.length; i++){ newHTML += '<span>'+text[i]+'<span>'; } textBox.innerHTML = newHTML;
Следующей задачей является поочередное появление символов и для этого потребуется написать рекурсивную функцию, то есть функцию, которая будет вызывать саму себя, пока весь текст не появится.
Как вы помните, выше я упоминал о курсоре. Чтобы все было, как в голливудском кино, определенно, нужно добавить мигающий курсор. А чтобы все совсем было как по-настоящему, добавим "плавающую" задержку для курсора, то есть паузу между набором слов, что создаст впечатление, будто текст набирает человек.
И так, возьмем все элементы span, по которым затем пройдемся рекурсивно. Поставим счетчик этих элементов (символов в span-ах), чтобы знать, какой обрабатывается в той или иной итерации рекурсии. И просто объявим переменную timeout, в которую будет записываться задержка для конкретной итерации.
let spans = textBox.querySelectorAll('span'), count = 0, timeout = 0;
Теперь приступим к разбору самой функции, создающей эффект печатающегося текста function typing_text(){...}
.
Каждый вызов этой функции визуализирует только один символ (а точнее, элемент span с заключенным в него символом) при помощи строки spans[count].classList.add('visible');
Эта строка добавляет элементу span CSS-класс visible.
Как мы решили выше, будем делать паузу между набором слов, и поэтому следующим условием, когда символ является пробелом, в переменную timeout будет записываться рандомное время задержки от 1 до 1000 миллисекунд. Если же содержимое span не является символом пробела, то присвоим задержку равную 50 миллисекундам, которая в целом задает скорость набора всего текста.
В дополнение к описанному выше, когда итерация функции обрабатывает символ пробела, мы должны отображать мигающий курсор, а для этого текущему span назначим CSS-класс cursor.
if(spans[count].innerText == ' ' || spans[count].innerHTML == ' '){ timeout = Math.floor(Math.random() * Math.floor(1000)); spans[count].classList.add('cursor'); }else{ timeout = 50; }
Перейдем к следующему условию функции «печатающей» текст. Это условие проверяет, прочитан ли весь текст, то есть, если счетчик прочитанных элементов меньше их общего числа, значит условие выполняется. И наоборот, если счетчик больше, сценарий прекращает свою работу, поскольку очередного вызова функции, набирающей текст уже не будет.
if (count < text.length - 1){ setTimeout(() => { spans[count].classList.remove('cursor'); count ++; typing_text(); }, timeout); }
В самом условии заключен метод setTimeout(), который позволяет запланировать (отложить) выполнение кода, заключенный внутри его конструкции через указанный интервал времени, который мы записали в переменную timeout.
Здесь же нам нужно прибавить к нашему счетчику символов count единицу, поскольку еще один символ был уже обработан, а затем, вызвать новую итерацию функции typing_text(), которая обработает очередной элемент.
Вот и весь код, позволяющий создать эффект печатающегося текста. Но осталась маленькая деталь! Для того, чтобы функция начала работать и сама себя вызывать рекурсивно, продолжая обрабатывать текст посимвольно, ее нужно первый раз вызвать, добавив строчку typing_text();.
С помощью JavaScript возможно сделать много интересных эффектов с текстом, но CSS3 предоставляет хорошие возможности, при использовании которых совместно со сценариями JS, позволяет не просто упростить код последнего, но и сделать эффекты весьма замысловатыми и красивыми.
Да, в первом примере мы уже использовали CSS-анимацию для текста, но сейчас самое время немного развить нашу фантазию. Давайте взглянем на парочку примеров, где для печатающегося текста, реализованного с помощью разобранного сценария JavaScript, будет добавлена более красочная CSS-анимация.
Анимация печатающегося текста.
Анимация текста, печатающегося волнами.
Надеюсь, по разбору первого примера с печатающимся текстом вы догадываетесь, как это работает. Во всяком случае, вы всегда можете подглядеть в исходный код.
А на этом я заканчиваю и желаю вам успехов!