Tasarım prototipinden üretim koduna: kontrollü kaosu Vue'ya taşımak
Bu site kod olarak değil, etkileşimli bir tasarım prototipi olarak başladı: devilyxrd, Controlled Chaos. Bu notta o prototipi sayfa sayfa Vue 3 ve TypeScript koduna nasıl taşıdığımı, neyi olduğu gibi aldığımı ve neleri sonradan ekleyip değiştirdiğimi anlatıyorum.
01Başlangıç: bir tasarım tuvali
Projenin ilk hali bir tasarım prototipiydi. Adı Controlled Chaos, Türkçesiyle kontrollü kaos. Prototipte sayfalar, renkler, tipografi ve hareket vardı; yanında bir de handoff panosu. Bu pano, Vue tarafında nasıl bir yapı kurulacağını ve hangi animasyonun hangi araçla yapılacağını tarif ediyordu.
Bir prototip görünüşü ve davranışı göstermek için iyi bir araç. Ama yönlendirme, SEO, erişilebilirlik ve performans onun işi değil. Benim işim o görüntüyü kaybetmeden bunları eklemekti. Bunu bir kerede değil, sırayla yaptım: önce tokenlar, sonra yapı, sonra sahneler, en son da iyileştirmeler.
02Önce tokenlar
Taşımaya renklerden başladım, çünkü geri kalan her şey onlara bağlı. src/styles/tokens.css dosyasının ilk satırı hâlâ handoff'taki ilgili bölümü işaret ediyor. Palet dokuz renkten oluşuyor: Void #0B0C11 zemin, Graphite #171922 ve Slate #292C38 yüzeyler, Soft #EDECF2 metin, Iris #A8A1F1 vurgu, Mauve #C7A8BE gizli modun rengi, Dusty #8999BF ikincil vurgu, Steel #8A8E9E sönük metin, Border #363945 çizgiler. Gövde metni için bunlara bir --body tonu ekledim.
:root {
--void: #0B0C11;
--graphite: #171922;
--slate: #292C38;
--soft: #EDECF2;
--iris: #A8A1F1;
--dusty: #8999BF;
--mauve: #C7A8BE;
--steel: #8A8E9E;
--border: #363945;
--body: #C9C8D3;
--f-display: 'Archivo', 'Syne', 'Space Grotesk', sans-serif;
--f-body: 'Space Grotesk', system-ui, sans-serif;
--f-mono: 'IBM Plex Mono', ui-monospace, monospace;
}
/* hidden mode: footer x clicked three times */
.app.mv { --iris: var(--mauve); }Tipografi üç aile: başlıklar için Syne, gövde için Space Grotesk, etiketler ve sayılar için IBM Plex Mono. Değişkenler --f-display, --f-body ve --f-mono adıyla tanımlı. Sonradan bir ayrıntı eklendi: yalnızca g ve ğ glifleri için kullanılan bir Archivo kesimi --f-display yığınının başında duruyor.
Tokenları en başa koymanın faydası gizli modda görüldü: .app.mv içindeki tek satır bütün vurgu rengini değiştiriyor. Renkler bileşenlere tek tek yazılmış olsaydı bu bir arama-değiştirme işine dönerdi.
03Sayfadan bileşene
Prototip sayfa sayfa düşünülmüştü; kod ise sorumluluğa göre düzenlenmeli. Klasörleri buna göre ayırdım. views her rota için bir dosya. features belirli bir sayfaya ait büyük sahneler: HeroScene, MarqueeBand, ProjectIndex gibi ana sayfa sahneleri ve playground'daki sekiz deneyle onları saran ExperimentShell. components her yerde kullanılan parçalar: header, menü, rota perdesi, komut paleti, imleç, footer, wordmark ve prosedürel kapak çizimleri. composables tekrar eden davranışlar için: hareket azaltma, pointer katmanı, rota geçişi, gizli mod.
İçeriği şablonlardan çıkarmak ayrı bir adımdı. Proje ve yazı listeleri src/content altında tipli dosyalarda; metinlerin kendisi src/i18n/locales içindeki tr.ts ve en.ts'te. Böylece bir yazı eklemek bir bileşene dokunmayı gerektirmiyor ve iki dildeki her anahtar tip denetiminden geçiyor.
Durum yönetimi için bir kütüphane eklemedim. Header, menü, palet, footer ve sayfaların paylaştığı durum src/stores/ui.ts içinde tek bir reactive nesne: menünün ve paletin açık olup olmadığı, toast metni, gizli mod sayacı, kaydırma durumu. Prototipteki etkileşimlerin çoğu bu birkaç alana indirgenebiliyordu; daha büyük bir araç, getirdiği yükü haklı çıkaracak kadar iş bulamazdı.
Prototip neyin görüneceğini söyler; kod neyin sürdürülebileceğini.
04Hareketin sahipleri
Prototipte her şey hareket ediyordu. Koda geçerken her hareketin bir sahibi olsun istedim. Handoff'taki kural basitti ve onu korudum: durum değişimleri CSS ve Vue geçişleriyle, rota perdesi ve hero girişi GSAP ile, geometri laboratuvarı Anime.js ile. Anime.js yalnızca lazy yüklenen /playground paketinde; router'daki bir yorum da bunu hatırlatıyor, ana sayfa paketi ona hiç ulaşmıyor. GSAP sonradan gizli moddaki shockwave ve harf saçılması için de kullanıldı.
Bu ayrım bir kural listesi gibi görünse de asıl faydası hata ayıklamada. Bir şey takıldığında hangi katmana bakacağımı biliyorum; aynı elemanı iki ayrı kütüphanenin aynı anda oynatması gibi bir durum oluşmuyor.
05Port bittikten sonra
İlk commit prototipin dokuz rotasını, TR/EN metinleri, komut paletini, tam ekran menüyü ve gizli modu getirdi. Asıl iş ondan sonra başladı. Performans tarafında hero'yu Vue'nun reaktivitesinden çıkarıp doğrudan DOM'a yazan bir döngüye çevirdim, ekran dışındaki animasyonları durdurdum, imleci yerel CSS imlecine taşıdım. SEO tarafında her rotayı build sırasında statik HTML'e render etmeye başladım, sonra İngilizceyi /en altına taşıyıp her sayfaya iki dilde ayrı adres verdim. En son prototipteki örnek içerikleri gerçek projeler, gerçek hakkımda metni ve gerçek yazılarla değiştirdim.
Geriye dönüp bakınca prototip bana en çok karar yükünü azaltarak yardım etti. Renk, aralık, tipografi ve hareket dili düşünülmüş olarak geldi; ben kodda mimariye, sınırlara ve ölçülebilir şeylere odaklanabildim.