§ Обяснено — технически дневник
Как е направено.
Девет действия, една страница, нищо освен CSS и малко JavaScript за разпръскване на звезди. Ето какво се случва отдолу — сцена по сцена, техника по техника.
§ 01
Безветрие — топъл хоризонт
Тих увод преди бурята.
Първата сцена е пейзаж в тоновете на кремав лен с една линия на хоризонта
и лодка, не по-широка от нокът. Изграден е с линеен градиент,
наслоени радиални сияния и разделител с дебелина един
пиксел, изрисуван като псевдоелемент. Лодката е малък вграден SVG,
прикрепен към хоризонта с position: absolute.
Бавното люлеене е суб-пикселов translateY keyframe
с продължителност 4 секунди и лека функция на плавност в двата края.
Нищо претенциозно — целта е да усетиш покой, без да е истински
покой. Всекидневните никога не са напълно тихи.
§ 02
Буря — дъжд, светкавица, налягане
Регистрирано свойство движи потъмняването на небето.
Бурята е моментът, в който CSS започва да изкарва наема си. Небето се
управлява от @property --storm-darkness — потребителско
свойство, регистрирано с типизиран синтаксис, така че да може да се
анимира гладко. Докато стойността расте, пакет от градиенти потъмнява,
а второ свойство --rain-density умножава непрозрачността
на слоя с дъжд.
Самият дъжд е един-единствен
repeating-linear-gradient, преместван с две различни
скорости — безплатен паралакс. Светкавицата са два SVG зигзага с кратък
пълноекранен проблясък, осигурен от mix-blend-mode: screen.
§ 03
Вълна — течно изместване
SVG филтри, приложени върху HTML.
Вълната използва двойка <feTurbulence> и
<feDisplacementMap>, дефинирани веднъж в скрит SVG в
началото на документа, и после извикани от CSS чрез
filter: url(#wave-displace). Турбулентността анимира своя
baseFrequency, което кара текстът да се надига и спуска,
сякаш през него тече бавна вълна.
Това е най-евтиният течен ефект, който можеш да си купиш. Едно препращане към филтър, без canvas, без шейдъри — браузърът прави сметките в своя композитор.
§ 04
Пауза — скрито звездно поле
Двеста звезди, шест съзвездия, един откриващ се кораб.
Слайдът „Пауза“ изглежда като един ред центриран текст върху празен мрак. Ако преместиш показалеца, фенерчето-курсор открива около 220 процедурно поставени звезди, съзвездията Голяма мечка, Лира, Орион, Гарван, Лебед и Дракон, четирите посоки, ред с лунни фази, нарисуван с молив ветроход и няколко падащи звезди.
Самото фенерче е radial-gradient маска, управлявана от
CSS променливите, които курсорът записва (--mx,
--my). Звездите са DOM елементи, които скриптът избягва
да поставя над центрирания текст — изключваща зона — така че
заглавието никога не се блъска с точките.
§ 05
Фигури в пространство — 3D без canvas
Чист transform-style: preserve-3d.
Всяко тяло в този слайд — кубът, тороидът с перки, двойната спирала,
възелът-трилистник, тунелът — е направено от обикновени
<div>-ове, подредени с
transform: rotateX / rotateY / translateZ. Родителят носи
perspective и transform-style: preserve-3d, а
децата обикалят чрез @keyframes.
Перките, стъпалата и мънистата се генерират при зареждане от
controller.js, който не прави нищо повече от това да
отпечата N деца с изчислен transform. Движението е изцяло
CSS — скриптът повече не работи след първоначалната постройка.
§ 06
Геометрия — мрежа с памет
Шестдесет и четири плочки, един hover.
display: grid от 64 плочки, всяка с transition
върху transform и background-color. При
движение на показалеца действието записва --px и
--py; всяка плочка изчислява разстоянието си до курсора с
calc() и повдигане на квадрат чрез pow() —
без JS на плочка, само математика в стиловия двигател.
§ 07
Кинетика — марширащ текст
Две линии, противоположни посоки, шев от светлина.
Кинетичната лента е един ред текст, дублиран и анимиран в
противоположни посоки чрез translateX. Градиентна маска
избледнява краищата, така че шевът никога не се разкрива. Сиянието по
средата е трик с background-clip: text — движещ се линеен
градиент, положен върху самите глифи, а не зад тях.
§ 08
Сливане — капки, които се познават
Класиката feGaussianBlur + праг.
Goo филтърът е стар фаворит: размажи групата, след което затегни
алфа-канала със стръмна feColorMatrix. Всеки два кръга,
достатъчно близки, за да се припокрият в размазването, ще се слеят.
Раздалечи ги и те се връщат като отделни капки. Кръговете са
div-ове с border-radius: 50%, въртящи се
всеки по собствена keyframe.
§ 09
Покой — спокойна вода, спокойно пространство
Огледален хоризонт, дишаща луна, пръстени, които не помръдват.
Финалното действие е отражение. Небето държи звездно поле, нарисувано
като пакет от radial-gradient-и с един пиксел; формите
в космоса — три концентрични пръстена около луната, два наклонени
планетни елипса, две малки планети — са нарочно неподвижни. Покой,
получил форма.
Под линията на хоризонта по-тъмен градиент носи вертикална колона
лунна светлина, три хоризонтални ленти с проблясване и шест разширяващи
се вълнички, ограничени до скромен размер. Заглавието отдолу е
дублирано, обърнато с transform: scaleY(-1), размазано и
избледняващо към долния си край чрез
mask-image — живо отражение във водната
повърхност, което се носи на всеки шест секунди с наклон от под един
градус.
§ Бележки
Няколко принципа
Една страница, един каскад. Всяка сцена зарежда от
един и същи набор стилове. Токените — цвят, тип, easing — живеят в
colors_and_type.css и се използват навсякъде другаде.
Движение със спирачка. Всеки анимиран блок зачита
prefers-reduced-motion. Витрината пак чете като витрина с
изключени анимации — просто по-тихо.
Без компромиси за типографията. Fraunces върши дисплейната работа с ос на оптичния размер, закована на 144 за hero мащаб. Inter носи тялото. JetBrains Mono маркира краищата — номера на секциите, етикети, футъри.
Нищо не е screenshot. Всеки пиксел, който виждаш, е изчислен. Промени размера, приближи, превключи на тъмен режим, принтирай го — композира се.