Мини-ролик на первом экране: 2D canvas вместо three.js
Пять сцен, которые переходят друг в друга, кликабельные шаги и повтор — без WebGL и без библиотек анимации. Разбор устройства и главной ошибки с часами.
На продающей странице первый экран — короткий ролик: заявка, отклик, смета, разработка, запуск. Сцены переходят друг в друга, шаги над картинкой кликабельны, в конце можно посмотреть снова. Всё это нарисовано в 2D-канвасе.
Почему не three.js
На главной странице сайта есть 3D-сцена с клавишами, и она стоит библиотеки — там объём и материалы. Здесь другой случай: карточка, лист и окно браузера — это один и тот же прямоугольник с закруглением на разных размерах. Именно поэтому сцены переходят друг в друга, а не сменяются: между ними интерполируется один объект.
Вторая причина практическая. Ролик играет сразу при открытии страницы, а библиотека на 700 килобайт означает ожидание. Первый экран, который ждёт загрузки, — не первый экран.
Ролик как функция одного числа
Вся сцена — чистая функция от времени. Это даёт бесплатно две вещи: шаги над картинкой становятся кнопками, которые просто ставят время в начало нужной сцены, и кнопка «смотреть снова» — это присвоение нуля.
Никаких таймлайнов и очередей анимаций. Есть время — есть кадр.
1const AT = { task: 0, reply: 2.1, brief: 5.0, build: 7.0, live: 9.2, end: 12.0 };
2
3// Часы: складываем ограниченные кадры, а не вычитаем время старта.
4clock.current.t += Math.min(0.2, seconds - previous);
Текст не рисуется в канвасе
Всё, что нужно прочитать — заголовок, подписи шагов, абзац под роликом — живёт в HTML над канвасом и под ним. Это не эстетическое решение: текст внутри канваса не выделяется, не читается программой чтения с экрана, не переводится и не индексируется.
Внутри канваса остались только надписи, которые являются частью картинки: заголовки внутри нарисованного окна браузера, кнопка внутри нарисованной карточки. Их роль — узнаваемость формы, а не чтение.
Мелочи, которые видно сразу
Канвас надо готовить под плотность экрана: умножить размеры на devicePixelRatio, ограничить множитель двойкой и один раз задать преобразование контексту. Без этого на телефоне всё выглядит мылом.
Перенос строк надо считать по измерениям, а не по количеству символов. Обрезка по числу знаков однажды разорвала слово «предложу» на «п» и «редложу» — ошибка, которую видно на скриншоте, но не видно в коде.
