Эффект рукописного текста в веб-интерфейсах строится на поэтапной прорисовке контуров букв. Основой выступает преобразование текста в SVG-кривые, поскольку только path-геометрия позволяет контролировать процесс «рисования» линии.
Типовой pipeline включает следующие этапы:
Ключевое ограничение SVG-текста заключается в том, что
<text> не предоставляет доступ к точной геометрии
букв. Поэтому применяется конвертация в <path>.
Механизм имитации рисования основан на управлении длиной обводки.
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
stroke-dasharray задаёт шаблон штриха и пробелаstroke-dashoffset сдвигает начало отрисовкиПри изменении stroke-dashoffset от полного значения к
нулю создаётся эффект постепенного появления линии.
Vivus — библиотека, предназначенная для SVG-анимации, ориентированной на эффект отрисовки.
Она автоматизирует:
new Vivus('svg-container', {
duration: 200,
type: 'oneByOne'
});
duration — длительность анимации в кадрахtype — способ отрисовкиsvg-container — id SVG-элементаSVG-текст должен быть преобразован в контуры. Обычно используется:
Результат представляет набор <path>:
<svg id="svg-container" viewBox="0 0 600 200">
<path d="M10 80 C 40 10, 65 10, 95 80" />
<path d="M110 80 C 140 10, 165 10, 195 80" />
</svg>
Каждый символ или часть букв становится отдельной геометрией.
Последовательная отрисовка каждого path:
new Vivus('svg-container', {
duration: 150,
type: 'oneByOne'
});
Используется для имитации письма, где каждая буква появляется отдельно.
Все элементы анимируются одновременно:
new Vivus('svg-container', {
duration: 150,
type: 'sync'
});
Применяется для быстрого появления сложных логотипов и декоративных надписей.
Смешанный режим с задержкой:
new Vivus('svg-container', {
duration: 200,
type: 'delayed',
delay: 80
});
Каждый элемент стартует с небольшим смещением во времени.
Для имитации реального письма важна последовательность штрихов, напоминающая движение пера.
Каждая буква разбивается на отдельные path:
Vivus последовательно прорисовывает их.
При использовании одного сложного path эффект становится более плавным:
<path d="M20 100 L50 20 L80 100 ..." />
Vivus анализирует общую длину контура и распределяет анимацию по всей траектории.
Скорость определяется параметром duration, но визуальное
ощущение зависит от длины path.
Пример:
new Vivus('svg-container', {
duration: 300,
type: 'oneByOne'
});
После завершения обводки часто применяется заполнение цвета.
svg path {
fill: transparent;
transition: fill 0.4s ease;
}
svg.finished path {
fill: black;
}
new Vivus('svg-container', {
duration: 200,
type: 'oneByOne',
onReady: function () {
this.el.classList.add('ready');
},
onComplete: function () {
this.el.classList.add('finished');
}
});
Vivus позволяет запускать анимацию по триггеру:
const animation = new Vivus('svg-container', {
duration: 180,
type: 'delayed',
start: 'manual'
});
document.addEventListener('click', () => {
animation.play();
});
Такой подход используется для:
Хотя Vivus не предоставляет сложные easing-функции напрямую, можно комбинировать с CSS-анимацией контейнера:
svg path {
stroke-dashoffset: 0;
animation: draw 2s ease-in-out;
}
@keyframes draw {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}
Vivus при этом может использоваться как генератор базовых значений длины пути.
Дополнительная выразительность достигается изменением
stroke-width:
path {
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
Комбинация:
stroke-linecap: round имитирует мягкий конец пераstroke-linejoin: round сглаживает соединения линийПри построении рукописного текста целого абзаца используется несколько SVG-слоёв:
<svg id="line1">...</svg>
<svg id="line2">...</svg>
<svg id="line3">...</svg>
Инициализация:
new Vivus('line1', { duration: 120, type: 'oneByOne' });
new Vivus('line2', { duration: 120, type: 'oneByOne' });
new Vivus('line3', { duration: 120, type: 'oneByOne' });
Синхронизация осуществляется через задержки или цепочку вызовов
onComplete.
Для точного имитирования письма применяется ручная сортировка path:
Пример структуры:
<path id="p1" d="..." />
<path id="p2" d="..." />
<path id="p3" d="..." />
Vivus отрисовывает элементы в DOM-порядке.
При большом количестве path возникают проблемы производительности:
Практика оптимизации:
will-change: stroke-dashoffsetРукописный эффект усиливается использованием шрифтов с естественной каллиграфией перед конвертацией в SVG:
После конвертации каждый глиф превращается в независимый path, который Vivus может анимировать как отдельный штрих.
Vivus часто используется как базовый слой анимации, поверх которого накладываются дополнительные эффекты:
feTurbulence)Пример комбинированного поведения:
new Vivus('svg-container', {
duration: 250,
type: 'delayed',
onFrame: function () {
// синхронизация внешних эффектов
}
});
Повторный запуск требует сброса состояния:
animation.reset().play();
Сброс восстанавливает исходные значения
stroke-dashoffset, позволяя повторить эффект письма без
пересоздания DOM.