Карандашный набросок, который заливается акварелью: разбираю эффект на SVG без библиотек

Boris0525 38 минут назад Объяснить с Карандашный набросок, который заливается акварелью: разбираю эффект на SVG без библиотек Средний 9 мин 774 CSS * JavaScript * HTML * Обработка изображений * Туториал Из песочницы...
Will Anthropic have the best AI model at the end of October 2026?
Вот важная новость с фронта ИИ: Boris0525 38 минут назад Объяснить с Карандашный набросок, который заливается акварелью: разбираю эффект на SVG без библиотек Средний 9 мин 774 CSS * JavaScript * HTML * Обработка изображений * Туториал Из песочницы Делал интерактивную открытку на день рождения и хотел, чтобы картинка не просто появлялась, а «рисовалась»: сначала карандашные линии, потом по касанию её заливает акварель, причём с рваным краем, как у краски, которая впитывается в бумагу. Готовых решений под такое не нашёл. Видео не подходило: нужна была реакция на тап и чёткость на любом экране.
В итоге всё собралось на чистом SVG, двух фильтрах и пятидесяти строках JS. Ниже разбираю по шагам, с кодом и граблями, на которые наступил. Что получится в конце:Контурный рисунок прорисовывается линия за линией.
Технические детали
По клику снизу вверх поднимается акварель, край у неё неровный и «живой». Вместе с фронтом краски летят золотые искры, а звук кисти синтезируется прямо в браузере. Интерактивное демо с ползунками, где можно покрутить параметры края: [Sketch → Watercolor Reveal (SVG feTurbulence mask)Шаг 1.
Два слоя одной картинкиНужны две версии одного рисунка:цветная — обычная картинка (JPG/WebP), сама акварель;контурная — SVG, где каждая линия рисунка отдельный без заливки, только со stroke. Контурную версию я получил трассировкой цветного рисунка в векторном редакторе. Важно, чтобы на выходе были именно линии (stroke), а не залитые фигуры, иначе прорисовывать будет нечего.
Слои кладутся друг на друга: preserveAspectRatio="xMidYMid slice" — это SVG‑аналог object-fit: cover: картинка заполняет экран и обрезается по краям, а не сжимается. У обоих слоёв он должен быть одинаковый, иначе линии разъедутся с цветом на экранах с другим соотношением сторон. Линии, которые рисуются самиКлассический приём через stroke-dasharray и stroke-dashoffset.
Отраслевые последствия
Делаем пунктир, у которого один штрих длиной во всю линию, а потом сдвигаем его так, чтобы штрих ушёл за пределы линии. Линия становится невидимой. Анимируем сдвиг обратно к нулю — и линия «прорисовывается».
Обычно длину каждой линии считают через getTotalLength(). Но есть трюк проще: атрибут pathLength="1" говорит браузеру «считай, что длина этой линии равна 1». Тогда для всех линий подходят одни и те же значения:.
draw е линии одновременно, картинка просто «проявится» целиком, и магии не будет. Нужен разнобой по времени: каждой линии своя задержка. async function drawLines(box, dur = 2, stagger = 1) { box.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.



