Анимированный ввод и удаление текста в placeholder input

Анимируем поле поиска, для привлечения внимания. Демонстрируем популярные или востребованные поисковые запросы.

/**
 * Функция для анимированного ввода и удаления текста в placeholder поля ввода.
 * @param {HTMLElement} inputElement - HTML-элемент поля ввода
 * @param {Array<string>} words - Массив слов для анимации
 * @param {Object} options - Настройки анимации
 */
function animateWords(inputElement, words, options = {}) {
    // Настройки по умолчанию
    const settings = {
        typingSpeed: 130,       // Скорость ввода (мс)
        deletingSpeed: 50,      // Скорость удаления (мс)
        pauseBeforeDelete: 1000, // Пауза перед удалением (мс)
        pauseBeforeNext: 500    // Пауза перед следующим словом (мс)
    };

    // Объединяем пользовательские настройки с настройками по умолчанию
    Object.assign(settings, options);

    let currentWordIndex = 0;
    let isDeleting = false;
    let charIndex = 0;
    let timeoutId = null;
    let isRunning = true;

    // Основная функция анимации
    function animate() {
        if (!isRunning) return;

        // Очищаем предыдущий timeout, если такой есть
        if (timeoutId) {
            clearTimeout(timeoutId);
        }

        // Получаем текущее слово из массива
        const currentWord = words[currentWordIndex];

        // Определяем текущую скорость анимации
        let speed = isDeleting ? settings.deletingSpeed : settings.typingSpeed;

        if (isDeleting) {
            // Удаляем по одной букве
            charIndex--;
        } else {
            // Печатаем по одной букве
            charIndex++;
        }

        // Устанавливаем текст в placeholder
        inputElement.placeholder = currentWord.substring(0, charIndex);

        // Условия для переключения между режимами ввода и удаления
        if (!isDeleting && charIndex === currentWord.length) {
            // Слово напечатано полностью, делаем паузу и начинаем удаление
            speed = settings.pauseBeforeDelete;
            isDeleting = true;
        } else if (isDeleting && charIndex === 0) {
            // Слово полностью удалено, переходим к следующему слову
            isDeleting = false;
            currentWordIndex = (currentWordIndex + 1) % words.length;
            speed = settings.pauseBeforeNext;
        }

        // Запускаем следующий шаг анимации
        timeoutId = setTimeout(animate, speed);
    }

    // Функция перезапуска анимации с начала
    function restart() {
        currentWordIndex = 0;
        isDeleting = false;
        charIndex = 0;
        if (isRunning) {
            animate();
        }
    }

    // Обработчики событий фокуса и потери фокуса
    function handleFocus() {
        pause();
        // Очищаем placeholder при фокусе
        inputElement.placeholder = '';
    }

    function handleBlur() {
        // Перезапускаем анимацию если поле пустое
        if (!inputElement.value) {
            restart();
            resume();
        }
    }

    // Добавляем обработчики событий
    inputElement.addEventListener('focus', handleFocus);
    inputElement.addEventListener('blur', handleBlur);

    // Запускаем анимацию
    animate();

    // Методы управления анимацией
    function pause() {
        isRunning = false;
        if (timeoutId) {
            clearTimeout(timeoutId);
        }
    }

    function resume() {
        if (!isRunning) {
            isRunning = true;
            animate();
        }
    }

    // Возвращаем объект с методами управления анимацией
    return {
        // Метод для изменения скорости
        setSpeed: function(newSettings) {
            Object.assign(settings, newSettings);
        },
        // Метод для остановки анимации
        stop: function() {
            pause();
            // Удаляем обработчики событий при остановке
            inputElement.removeEventListener('focus', handleFocus);
            inputElement.removeEventListener('blur', handleBlur);
        },
        // Метод для паузы
        pause,
        // Метод для возобновления
        resume,
        // Метод перезапуска
        restart
    };
}

Пример использования

document.addEventListener('DOMContentLoaded', () => {
    const inputField = document.querySelector('#search-input');

    const wordsToAnimate = [
        'Каменная краска',
        'Фасадная краска',
        'Текстурная',
        'Для интерьера',
    ];

    animateWords(inputField, wordsToAnimate);
});