Выполняю, подождите...
 
 
Библиотека

Эффект печатающегося текста

С помощью эффектов и анимации текста можно сделать занимательные веб-страницы, и в этом уроке мы рассмотрим один из таких эффектов, а именно, разберем, как сделать печатающийся текст с помощью JavaScript.

Самонабирающийся текст нередко можно встретить в сценах фантастического кино в жанре киберпанк. Первое, что всплывает в памяти, фильм "Матрица" и сцена, когда Тринити посылает сообщение Нео, печатающееся на экране его монитора.

Cцена из «Матрицы» с печатающимся текстом

Cцена из кинофильма «Матрица» с печатающимся текстом.

Что ж, эту сцену можно взять за основу нашего будущего текстового эффекта для веб-страницы. Таким образом, конечный результат будет выглядеть вот так.

Эффект печатающегося текста в стиле сцены из «Матрицы» с помощью JavaScript.

Сценарий 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 и CSS-анимации

С помощью JavaScript возможно сделать много интересных эффектов с текстом, но CSS3 предоставляет хорошие возможности, при использовании которых совместно со сценариями JS, позволяет не просто упростить код последнего, но и сделать эффекты весьма замысловатыми и красивыми.

Да, в первом примере мы уже использовали CSS-анимацию для текста, но сейчас самое время немного развить нашу фантазию. Давайте взглянем на парочку примеров, где для печатающегося текста, реализованного с помощью разобранного сценария JavaScript, будет добавлена более красочная CSS-анимация.

Анимация печатающегося текста.

Анимация текста, печатающегося волнами.

Надеюсь, по разбору первого примера с печатающимся текстом вы догадываетесь, как это работает. Во всяком случае, вы всегда можете подглядеть в исходный код.

А на этом я заканчиваю и желаю вам успехов!