diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md index 445b797..ae67355 100644 --- a/docs/tasarim/DESIGN.md +++ b/docs/tasarim/DESIGN.md @@ -136,10 +136,11 @@ Seçici `src/components/tema-secici.tsx` (footer'da), sağlayıcı `src/componen **Geçiş ve kısayol (7 Eki 2026):** tema değişimi anlık değildir; yeni tema KolayTercih işaretinin biçiminde önce ekranın altından ortaya süzülür, sonra merkezden büyüyerek ekranı kaplar — büyüme boyunca logo normal, boşluklu -hâliyle görünür; en büyük haline yaklaştıkça kareler arası boşluklar -merkezden dışa doğru yumuşak biçimde kapanır (View Transitions + CSS +hâliyle görünür; büyümenin ikinci yarısında kareler arasında kalan eski +görüntü tam ekran dolguyla yeni temaya solar. Ekranda tek silüet vardır, +ikinci bir şekil büyümez ("logo içinde logo" olmaz). (View Transitions + CSS maskesi, maskeyi motion sürer: `src/lib/tema-gecisi.ts`, `globals.css` -`.kt-tema-gecis`; hareket azaltılmışsa düz değişir). +`.kt-tema-gecis`; hareket azaltılmışsa düz değişir.) `D` tuşu açık ↔ koyu geçişi yapar (`src/components/tema-kisayolu.tsx`); ipucu seçicinin altında `Kbd` ile durur, başka yere kopyalanmaz. Header'daki Beta rozeti `/surum-notlari`na bağlantıdır. diff --git a/public/kolay-tercih-mark-dolu.svg b/public/kolay-tercih-mark-dolu.svg deleted file mode 100644 index 796bfa8..0000000 --- a/public/kolay-tercih-mark-dolu.svg +++ /dev/null @@ -1,15 +0,0 @@ - - KolayTercih - - - - diff --git a/src/app/globals.css b/src/app/globals.css index 5267f7e..a0efa8c 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -478,22 +478,22 @@ } /* Tema geçişi (DESIGN.md §2.3, lib/tema-gecisi.ts): tema değişirken yeni - görüntü, KolayTercih işaretinin biçiminde önce ekranın ALTINDAN ortaya + görüntü, KolayTercih işaretinin biçiminde önce ekranın altından ortaya süzülür, sonra merkezden büyüyerek ekranı kaplar. Eski görüntü yerinde - durur; yeni görüntünün maskesi üç katman (hepsi `add` ile toplanır, - mask-composite varsayılanı add — bu yüzden sıralama yalnızca okunurluk - içindir): - (1) işaretin NORMAL çizimi (kolay-tercih-mark.svg'nin gömülü kopyası — kareler arası boşluk - görünür, logo logonun kendisi gibi durur), merkezi --kt-tema-x/y'de, - boyu --kt-tema-kenar: uçuş ve büyüme boyunca bu görünür; - (2) aynı geometride BOŞLUKLARI DOLU çizim (kolay-tercih-mark-dolu.svg), - boyu --kt-tema-kenar × --kt-tema-kapanis (0 → 1): logo en büyük haline - ulaşmaya yakın dolu çizim merkezden dışa doğru büyür, kareler arası - boşlukları yumuşak biçimde kapatır; - (3) tam ekran dolgu: --kt-tema-dolgu (0 → 1) ile işaret ekranı tam - kapsadıktan sonra dış çentiklerde kalan eski zeminin son anda dolması. - Yuvarlak büyüme yok — logo ekranı kaplayınca geçiş tamamlanır. - Konum, boy ve dolgular motion ile sürülür (lib/tema-gecisi.ts); buradaki + durur; yeni görüntünün maskesi iki katman (mask-composite varsayılanı + add, toplanır): + (1) işaretin çizimi (kolay-tercih-mark.svg'nin gömülü kopyası — üç kare, + aralarındaki boşlukla, logo logonun kendisi gibi durur), merkezi + --kt-tema-x/y'de, boyu --kt-tema-kenar; + (2) tam ekran dolgu, alfası --kt-tema-dolgu (0 → 1): büyümenin ikinci + yarısında kareler arasında ve ekran kenarlarında kalan eski görüntü + yumuşakça yeni temaya solar. İkinci bir şekil yok — "logo içinde logo" + görünmesin (8 Eki 2026, Bilal). + SVG data URI olarak gömülü, dosyadan url() ile DEĞİL: Chrome, view + transition pseudo elemanında dosyadan yüklenen birden çok maske + katmanını tümden şeffaf çiziyordu. Çizim public/kolay-tercih-mark.svg + ile aynı geometridir; o değişirse burası da güncellenir. + Konum, boy ve dolgu motion ile sürülür (lib/tema-gecisi.ts); buradaki kt-tema-omur yalnızca geçişin pseudo elemanı motion bitene kadar yaşasın diye durur (süre --kt-tema-sure, JS'den gelir). Hareket azaltılmışsa JS geçişi hiç başlatmaz, tema düz değişir. */ @@ -502,11 +502,6 @@ inherits: true; initial-value: 0px; } -@property --kt-tema-kapanis { - syntax: ""; - inherits: true; - initial-value: 0; -} @property --kt-tema-dolgu { syntax: ""; inherits: true; @@ -526,15 +521,7 @@ } .kt-tema-gecis::view-transition-new(root) { z-index: 2; - /* İki SVG de data URI olarak gömülü, dosyadan url() ile DEĞİL: Chrome'da - view-transition pseudo elemanı dosyadan yüklenen ikinci bir maske - katmanını (boyu 0'dan büyük olduğu an) tümden şeffaf çiziyor — logo - hiç görünmüyordu (8 Eki 2026 tanısı). Gömülü hâlde iki katman da - doğru birleşiyor. Çizimler public/kolay-tercih-mark.svg ve - public/kolay-tercih-mark-dolu.svg ile aynı geometridir; oradaki dosya - değişirse burası da güncellenir. */ mask-image: - url("data:image/svg+xml,"), url("data:image/svg+xml,"), linear-gradient( rgb(0 0 0 / var(--kt-tema-dolgu)), @@ -542,13 +529,9 @@ ); mask-repeat: no-repeat; mask-size: - calc(var(--kt-tema-kenar) * var(--kt-tema-kapanis)) - calc(var(--kt-tema-kenar) * var(--kt-tema-kapanis)), var(--kt-tema-kenar) var(--kt-tema-kenar), 100% 100%; mask-position: - calc(var(--kt-tema-x) - var(--kt-tema-kenar) * var(--kt-tema-kapanis) / 2) - calc(var(--kt-tema-y) - var(--kt-tema-kenar) * var(--kt-tema-kapanis) / 2), calc(var(--kt-tema-x) - var(--kt-tema-kenar) / 2) calc(var(--kt-tema-y) - var(--kt-tema-kenar) / 2), 0 0; diff --git a/src/lib/tema-gecisi.ts b/src/lib/tema-gecisi.ts index f6826f5..82178fd 100644 --- a/src/lib/tema-gecisi.ts +++ b/src/lib/tema-gecisi.ts @@ -2,8 +2,7 @@ // çevirmez; yeni tema, KolayTercih işaretinin biçiminde önce ekranın altından // ortaya süzülür, sonra merkezden büyüyerek ekranı kaplar. View Transitions // API + CSS maskesi (globals.css `.kt-tema-gecis`) eski/yeni görüntü çiftini -// kurar; maskenin konumu, boyu, boşluk kapanışı ve son dolgu motion ile -// sürülür. Tarayıcı View Transitions bilmiyorsa ya da kullanıcı hareketi +// kurar; maskenin konumu, boyu ve son dolgu motion ile sürülür. Tarayıcı View Transitions bilmiyorsa ya da kullanıcı hareketi // azaltmışsa tema düz değişir. import { animate, type AnimationPlaybackControls } from "motion"; @@ -11,32 +10,18 @@ import { animate, type AnimationPlaybackControls } from "motion"; /** Geçiş sırasında 'de duran sınıf (globals.css). */ const GECIS_SINIFI = "kt-tema-gecis"; -// Saniye. Faz 1 (uçuş): işaret ekranın altından ortaya gelir — normal, -// boşluklu hâliyle. Faz 2 (kaplama): merkezden büyüyerek ekranı aşar; -// kaplamanın KAPANIS_BASI…KAPANIS_BITIS aralığında dolu çizim merkezden -// dışa büyür ve kareler arası boşlukları kapatır (en büyük hâle ulaşmadan). -// EASE fazlar arasında geçişin eski koreografisiyle aynı hissi verir. +// Saniye. Faz 1 (uçuş): işaret ekranın altından ortaya gelir. Faz 2 +// (kaplama): merkezden büyüyerek ekranı aşar; DOLGU_BASI'ndan sonra tam ekran +// dolgu alfası yükselir ve kareler arasında / kenarlarda kalan eski görüntü +// yeni temaya solar. Ekranda tek silüet vardır, ikinci bir şekil büyümez. const UCUS_SURE = 0.45; const KAPLAMA_SURE = 0.6; -const KAPANIS_BASI = 0.55; -const KAPANIS_BITIS = 0.9; +const DOLGU_BASI = 0.5; const EASE = [0.65, 0, 0.35, 1] as const; // CSS'teki kt-tema-omur'un süresi: motion bitmeden pseudo eleman kalkmasın // diye toplamın biraz üstü (globals.css'te --kt-tema-sure ile okunur). const GECIS_SURESI = UCUS_SURE + KAPLAMA_SURE + 0.1; -// İşaretin dış kenarları (public/kolay-tercih-mark-dolu.svg, 180'lik viewBox; -// orijinal logonun boşlukları doldurulmuş çizimi, dış uzantılar aynı): -// x 27–147, y 29–151. Merkeze (90) göre oranlar — dolgu, bu sınır kutusu -// ekranı tam kapsadığı andan itibaren dolar; erken dolarsa ekrandaki eski -// zemin topluca solardı. -const KENAR_ORAN = { - sol: (90 - 27) / 180, - sag: (147 - 90) / 180, - ust: (90 - 29) / 180, - alt: (151 - 90) / 180, -} as const; - let suruyor = false; /** @@ -73,27 +58,13 @@ export function temayiGecisle(uygula: () => void) { const merkezY = boy / 2; const baslangicY = boy + ucusKenar / 2; // Kaplama merkezden ekranın en uzak köşesine kadar büyümeli. İşaretin - // görünür karesi viewBox'ın ~%67'si; kenar bu oranla çarpılır ki en büyük - // hâlde köşe karesi bile ekranı aşsın (eski hesapla aynı çarpan). - const sonKenar = Math.ceil(Math.hypot(merkezX, merkezY) * 3.4); - // Dolgu, işaretin dış kutusu ekranı tam kapsadığı anda başlar (erken - // dolarsa marka henüz ekrana ulaşmadan eski zemin topluca solardı). Alt - // sınır 0.9: kapsama hesaba katılmayan dar bir marjla geç kalırsa bile - // dolgu kaplamanın son ~%10'unda bitsin; aksi hâlde ekranın köşelerinde - // eski zemin belirgin biçimde kalır. - const kapsaKenar = Math.max( - en / 2 / Math.max(KENAR_ORAN.sol, KENAR_ORAN.sag), - boy / 2 / Math.max(KENAR_ORAN.ust, KENAR_ORAN.alt), - ); - const dolguBasi = Math.min( - 1, - Math.max((kapsaKenar - ucusKenar) / (sonKenar - ucusKenar), 0.9), - ); + // görünür karesi viewBox'ın ~%67'si; kenar bu oranla çarpılır ki kareler + // ekranı geniş ölçüde kaplasın — kalan boşlukları dolgu solması kapatır. + const sonKenar = Math.ceil(Math.hypot(merkezX, merkezY) * 3); kok.style.setProperty("--kt-tema-x", `${merkezX}px`); kok.style.setProperty("--kt-tema-y", `${baslangicY}px`); kok.style.setProperty("--kt-tema-kenar", `${ucusKenar}px`); - kok.style.setProperty("--kt-tema-kapanis", "0"); kok.style.setProperty("--kt-tema-dolgu", "0"); kok.style.setProperty("--kt-tema-sure", `${GECIS_SURESI}s`); kok.classList.add(GECIS_SINIFI); @@ -118,22 +89,11 @@ export function temayiGecisle(uygula: () => void) { ease: EASE, onUpdate: (kenar) => kok.style.setProperty("--kt-tema-kenar", `${kenar}px`), }), - // Kapanış: dolu çizimin boyu kenar × kapanış — büyümenin ortasından - // sonuna doğru boşluklar merkezden dışa dolar, logo en büyük hâle - // ulaşmadan kapanır. Boyut sürüldüğü için ek bir katmanın alfa - // çakışması gerekmez; maske toplamı (add) değişmez. + // Dolgu: büyümenin ikinci yarısında kareler arasında ve ekran + // kenarlarında kalan eski görüntü yeni temaya solar. animate(0, 1, { - duration: KAPLAMA_SURE * (KAPANIS_BITIS - KAPANIS_BASI), - delay: UCUS_SURE + KAPLAMA_SURE * KAPANIS_BASI, - ease: EASE, - onUpdate: (kapanis) => kok.style.setProperty("--kt-tema-kapanis", `${kapanis}`), - }), - // Dolgu: işaretin dış çentiklerinde kalan eski zemin son anda dolar — - // ekranı kapsayan boşluklar (kareler arası şeritler) maskenin kendisinde - // dolu çizimle kapanmıştır, burada değil. - animate(0, 1, { - duration: KAPLAMA_SURE * (1 - dolguBasi), - delay: UCUS_SURE + KAPLAMA_SURE * dolguBasi, + duration: KAPLAMA_SURE * (1 - DOLGU_BASI), + delay: UCUS_SURE + KAPLAMA_SURE * DOLGU_BASI, ease: EASE, onUpdate: (dolgu) => kok.style.setProperty("--kt-tema-dolgu", `${dolgu}`), }),