"Swarm" nasıl yapıldı?
4.200 parçacık FINDIE logotipini yazıyor, basılı tutunca sürüye dönüşüyor, scroll'da DESCRIBE → BUILD → QUEUE → LAND kelimelerine şekilleniyor. Bu rehber, o motorun ve sayfanın nasıl kurulduğunu anlatır. Framework yok, build yok: tek HTML dosyası.
Konsept: sürü = ajan filosu
Findie bir AADE (Autonomous Agentic Development Environment): Kanban'a kart bırakırsın, yapay zekâ ajanları izole git worktree'lerinde inşa eder, seri merge kuyruğu işi indirir, main yalnızca fast-forward ilerler. Yani ürünün özü: tek tek zayıf ama birlikte iş bitiren çok sayıda otonom birim. Sığırcık sürüsü (murmuration) bunun doğadaki karşılığı. Sayfanın imza tekniği de bu yüzden parçacık sürüsü: ürünün metaforu, süsü değil.
Ders: önce "bu ürünün doğadaki/dünyadaki karşılığı ne?" sorusunu cevapla, sonra o tek fikri sayfanın her köşesine uygula. Tek güçlü fikir, on ortalama bölümden iyidir.
Parçacık motoru (vanilla canvas)
Motor ~150 satır; kütüphane yok. İki mod var:
- MORPH: her parçacık kendi hedef pikseline yay (spring) ile çekilir:
v = v*0.82 + (hedef-konum)*0.06. Üstüne küçük bir sinüs titreşimi eklenir ki harfler "nefes alsın". - FLOCK (boids): ayrılma + hizalanma + kümelenme. Komşu araması için ekran 46px hücrelere bölünür (spatial hash); 4.200 parçacıkta bile O(n) kalır, 60fps korunur.
Kelime nasıl parçacığa dönüşür? Görünmez bir canvas'a Bricolage Grotesque (800) ile kelime yazılır, getImageData ile alfa kanalı taranır, dolu pikseller belirli adımlarla örneklenir:
ox.font = "800 " + fontSize + "px 'Bricolage Grotesque'";
ox.fillText(word, W/2, H*0.45);
const img = ox.getImageData(0,0,W,H).data;
for (let y=0; y<H; y+=step)
for (let x=0; x<W; x+=step)
if (img[(y*W+x)*4+3] > 128) targets.push(x,y);
// step, nokta sayısı ~N'e yaklaşana dek büyütülür (adaptif yoğunluk)
- Hedef sayısı parçacık sayısından azsa artan parçacıklar "toz" olur: %10 opaklıkla süzülürler.
- İz efekti: her karede ekranı silmek yerine
rgba(5,7,11,.38)ile boyanır; hareket kuyruk bırakır. - Renk: MORPH'ta krem, FLOCK'ta ve finalde Findie mavisi (
#037BFCailesi, markanın kendi rengi). Tek accent, markadan geliyor. - Fare MORPH'ta bir agent: yarıçapına giren kelime noktaları (task'lar) imlece atanır, altın açılı (filotaksi) yörünge yuvalarında imlecin etrafında döner ve ince mavi dispatch çizgileriyle merkeze bağlanır. Küme imleç durdukça sabittir; imleç uzaklaşınca task'lar maviden beyaza parlayarak harfteki yerlerine geri iner. İmlecin altında mono bir "NN TASKS" sayacı yazar (aynı anda en çok 56 task).
- FLOCK'ta fare klasik itme (repulsion) uygular; "basılı tut" sürüyü serbest bırakır, bırakınca kelimeye geri toplanır.
Scroll sinematografisi (GSAP ScrollTrigger)
Kelime morph sahnesi pin + scrub ile kurulu: bölüm ekrana yapışır, 3.2 ekran boyu scroll boyunca ilerleme 0→1 akar, her çeyrekte kelime değişir:
ScrollTrigger.create({
trigger: '#morph', start: 'top top',
end: '+=320%', pin: true, scrub: true,
onUpdate(self){
const s = Math.min(3, Math.floor(self.progress * 4));
if (s !== seg) { seg = s; form(WORDS[s]); /* caption swap */ }
}
});
Sahneden çıkınca (onLeave) sürü serbest moda düşer ve %16 opaklığa iner: sayfanın geri kalanında arka planda yaşamaya devam eder. Final bölümüne girince geri toplanıp mavi SHIP kelimesini yazar. Canvas position:fixed tek katmandır; tüm sayfa aynı simülasyonun içinde geçer.
Tipografi ve dil
- Bricolage Grotesque 800 (dev display: yumuşak hatlı, karakterli) + Geist (gövde; ürünün kendi UI fontu) + Geist Mono (telemetri). Hepsi woff2 self-host; ilk boyamada üçüncü parti istek yok. İlk sürüm Archivo Black ile fazla sert duruyordu; kullanıcı geri bildirimiyle hatlar yumuşatıldı: display değişti, butonlar 16px+ radius aldı, başlıklar sentence-case oldu.
- Ölçek korkusuzca büyük: doctrine satırları
clamp(26px, 4.6vw, 64px). Hover'da satır marka mavisine invert olur; ekran görüntüsü "polaroid" gibi yana düşer. - Telemetri dili dünyayı kurar: "LIVE SIMULATION · 4200 AGENTS IN FORMATION", "HOLD ANYWHERE · RELEASE THE SWARM". Küçük mono satırlar sayfaya "çalışan sistem" hissi verir.
Detay katmanı
- Preloader: 1 saniyelik "SPAWNING SWARM" + yüzde sayacı; perde yukarı kalkarken parçacıklar logoya toplanıyor. Yükleme değil, sahne girişi.
- Custom cursor: mavi halka,
mix-blend-mode:screen; link üstünde büyür, basılı tutunca 2.2x. Dokunmatik cihazda tamamen kapalı. - Grain + vignette: sabit, tıklama geçirmez iki katman; %7 film greni her şeyi birbirine yapıştırır.
- Erişilebilirlik: canvas dekoratif (
aria-hidden); anlatının tamamı gerçek DOM metni.prefers-reduced-motion'da simülasyon tek kare çizer, pin sahneleri normal akışa döner.
Üç turlu eleştiri döngüsü
- Tur 1 (yıkım): İlk sürüm "temiz bir SaaS sayfası"ydı: yıldız alanı, bento grid, ölçülü animasyonlar. Teknik olarak kusursuz, duygusal olarak unutulabilir. Referans işlerle yan yana koyunca karar netti: çöpe at, imza tekniği etrafında yeniden kur.
- Tur 2 (yeniden inşa): Parçacık motoru + pin sahnesi + brutalist tipografi. Ekran görüntüleriyle denetim: cursor açılışta köşede takılı kalıyordu (ilk harekete kadar gizlendi), SHIP finali soluktu (parlak marka moduna bağlandı), harf dolgusu inceydi (parçacık boyutu büyütüldü).
- Tur 3 (cila): Fold / morph ortası / final / tam sayfa / mobil çekimleri, konsol hata taraması, canlı deploy doğrulaması.
Sen de kur
# 1. Ürünün metaforunu bul; imza tekniğini ona göre seç
# 2. Text-to-particle: offscreen canvas + getImageData + adaptif örnekleme
# 3. İki modlu motor: spring-morph + boids (spatial hash ile)
# 4. GSAP ScrollTrigger: pin + scrub, çeyreklerde kelime değiştir
# 5. Fixed canvas = tüm sayfa tek simülasyonun içinde
# 6. Üç tur acımasız eleştiri; her turda screenshot + kusur listesi
npx wrangler pages deploy ./site --project-name=my-world