"Sealed" nasıl yapıldı?
Ekranda şifreli paketlerden bir nehir akıyor; scroll'da parçacıklar önce bir QR koduna, sonra bir asma kilide şekilleniyor; finalde SEALED kelimesini yazıyorlar. Bu rehber, aynı parçacık motorunun üç farklı "hedef kaynağıyla" nasıl üç sahneye dönüştüğünü anlatır.
Konsept
Findie'nin mobil hikâyesi üç cümle: telefonunu bir QR ile eşleştirirsin (host'un X25519 anahtarı telefona sabitlenir), oturumlar uçtan uca mühürlenir, aradaki relay yalnızca şifreli baytları taşır. Sayfanın üç pin-sahnesi birebir bu üç cümle: QR → kilit → akış. Görsel anlatı ile ürün gerçeği aynı şey; süs yok.
Tek motor, üç hedef kaynağı
SWARM sayfasındaki parçacık motoru (spring-morph + hedef örnekleme) burada genelleştirildi: hedef noktaları artık yalnızca metinden değil, herhangi bir alpha maskesinden gelebiliyor:
// ortak: offscreen canvas'a İSTEDİĞİN ŞEYİ çiz, alpha'yı örnekle
function sampleAlpha() {
const img = ox.getImageData(0,0,W,H).data;
for (adaptif step) topla: img[(y*W+x)*4+3] > 128 → hedef(x,y)
}
formWord('SEALED') // metin çiz → örnekle
formQR() // prosedürel QR deseni çiz → örnekle
formLock() // roundRect gövde + arc kulp + keyhole → örnekle
- QR: gerçek bir QR değil, "QR grameri": üç köşe bulucu (finder) karesi, timing çizgileri, %46 rastgele modül. Sabit tohumlu (seeded) rastgele üretim: her yüklemede aynı desen, taranabilir bir veri yok.
- Kilit: canvas path'leriyle çizilir; anahtar deliği
destination-outile oyulur. Parçacıklar deliğin çevresini kendiliğinden boş bırakır. - Akış (flow) modu: hedef yok; her parçacık kendi "şeridinde" (lane) soldan sağa akar, sinüsle salınır, ekran dışına çıkınca başa sarar.
Şifreli paket kapsülleri
Nehrin üstünde 16 "paket" yüzer: yuvarlak köşeli kapsüller içinde glyph dizileri (◆▲$#@…). Her paketin kendi hızı, salınımı ve metni var; glyph'ler ara ara kendiliğinden değişir. Basılı tutunca tüm paketler scramble moduna geçer: okumaya çalıştıkça daha hızlı şifrelenir. Ekran dışına çıkan paket yeniden doğar.
Performans: kapsüller roundRect + tek fillText; 16 adet, maliyetsiz. 3.600 nokta parçacık ise saf fillRect.
Pin sahnesi (GSAP ScrollTrigger)
ScrollTrigger.create({
trigger:'#pair', start:'top top', end:'+=260%', pin:true, scrub:true,
onUpdate(self){
const s = Math.min(2, Math.floor(self.progress * 3));
if (s !== seg) { seg = s; ['qr','lock','flow'][s] sahnesine morph; caption swap; }
}
});
Sahneden çıkınca sürü %15 opaklıkla akış moduna döner ve sayfanın geri kalanında arka planda yaşar; finalde parlak markaya dönüp SEALED yazar (renk lerp: buz beyazı → #3ba0ff).
İki uç kompozisyonu
"One board. Both ends." bölümünde telefon ve masaüstü çerçeveleri saf CSS: yüksek radius'lu (44px) dış kabuk + iç ekran, aralarında repeating-linear-gradient ile akan kesikli "e2ee" hattı. Telefon ekranındaki görüntü ayrı bir mobil ekran görüntüsü değil: aynı board görüntüsünün object-position ile sol kesiti. Dar ekranda hat dikeyleşir, kompozisyon alt alta düşer.
Marka sistemi (yumuşak hatlar)
- Bricolage Grotesque 800 display + Geist / Geist Mono (ürünün kendi fontları). Başlıklar sentence-case.
- Findie mavisi iki ton:
#037BFC(butonlar, marquee) ve#3ba0ff(vurgu, çizgiler). - Her interaktif yüzey yüksek radius: butonlar 16-22px, kapsüller 13px, cihaz çerçeveleri 44px, doctrine satır hover'ı 20px.
- Custom cursor, boot sayacı, marquee, hover-invert satırlar: SWARM ailesinin devamı; iki sayfa aynı dilin iki lehçesi.
Üç turlu eleştiri döngüsü
- Tur 1: QR ve kilit morph'ları ilk denemede oturdu; scroll ölçümünde kilit sahnesi yanlış noktada yakalandı, segment eşikleri doğrulandı.
- Tur 2: mobilde nehir ve paketler başlığın üzerine akıyordu; nehir bandı mobilde üst 1/3'e sıkıştırıldı (masaüstünde .24-.66, mobilde .09-.39).
- Tur 3: tam sayfa + mobil + konsol taraması + canlı deploy doğrulaması.
Sen de kur
# 1. Parçacık motorunu "alpha maskesinden hedef" üzerine kur
# 2. Hedef kaynakları: metin / prosedürel QR / path çizimi; hepsi aynı örnekleyici
# 3. Akış modu: lane + sinüs + wrap; paketler ayrı hafif katman
# 4. Pin+scrub: üç sahne = ürünün üç cümlesi
# 5. Mobilde bantları daralt; reduced-motion'da tek kare
npx wrangler pages deploy ./site --project-name=my-sealed