From 87f011519a4ff2c2c2117cae514dfd8d5ad9495d Mon Sep 17 00:00:00 2001 From: bilalgursen Date: Sun, 11 Oct 2026 02:03:06 +0300 Subject: [PATCH 1/2] =?UTF-8?q?feat(program-ayrinti):=20a=C3=A7=C4=B1l?= =?UTF-8?q?=C4=B1=C5=9Fta=20logo=20kareleri=20ba=C5=9Fl=C4=B1=C4=9Fa=20de?= =?UTF-8?q?=C4=9Fil=20g=C3=B6sterge=20karelerine=20d=C3=B6n=C3=BC=C5=9F?= =?UTF-8?q?=C3=BCr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logonun üç karesi içerikteki kart alanlarına (kontenjan, netler, istihdam) uçup onların boyuna büyür; kart kareden belirir. Başlık ilk andan görünür. Hedefi olmayan kare olduğu yerde söner. Co-Authored-By: Claude Opus 5.5 --- docs/tasarim/DESIGN.md | 9 ++- src/components/ui/acilis-sahnesi.tsx | 76 ++++++++++++------- .../katalog/components/program-ayrinti.tsx | 28 +++---- 3 files changed, 68 insertions(+), 45 deletions(-) diff --git a/docs/tasarim/DESIGN.md b/docs/tasarim/DESIGN.md index b1f6396..20d77f9 100644 --- a/docs/tasarim/DESIGN.md +++ b/docs/tasarim/DESIGN.md @@ -723,8 +723,13 @@ sihirbaz modalı içindir; yeni bir ayrıntı için `Dialog` açılmaz. altında yan yana durur, dokununca yer değiştirir. Odak dönüşen öğeyle gider (açılınca çarpı, kapanınca kare). "Hareketi azalt"ta dönüşüm yok (`MotionConfig reducedMotion="user"`). Verisi olmayan bölümün karesi çizilmez. 10 Ekim'deki "bu çekmecede kart yok" kuralı bu üç bölüm için - kalktı; koşullar, üniversite ve kaynak satırı kartsız kalır. Açılış sahnesi değişmedi (logo → - başlık); kareler tek `data-sonra` bloğu olarak netleşir. + kalktı; koşullar, üniversite ve kaynak satırı kartsız kalır. +- **11 Eki 2026 — logo → gösterge kareleri:** Bilal: "logonun dönüştüğü başlık olmamalı, içerikteki + kart alanları olmalı." Logonun üç karesi artık başlığa değil, aşağıdaki gösterge karelerine uçar + ve onların boyuna büyür (`data-logo-hedef="sol|sag-ust|sag-alt"`, `AcilisSahnesi` sözleşmesi; + kareler sırayla sol / sağ üst / sağ alt logo karesini alır); kare uçuşun son yarısında solar, + kart o sırada belirir. Hedefi olmayan logo karesi (verisi olmayan bölüm) olduğu yerde söner. + Başlık ilk andan görünür. 10 Ekim'deki logo → başlık dönüşümü kalktı. - **10 Eki 2026 — büyük logo, logo → başlık (morph):** Bilal: "logo küçücük kalmış; logolar küçülürken başlıktaki yazıya morph olsun." Logo kabı `size-44` (akademik göstergelerdeki logoyla aynı ölçek). Kareler sönmek yerine küçülerek (scale 0.2) başlık yazısının üç eşit diff --git a/src/components/ui/acilis-sahnesi.tsx b/src/components/ui/acilis-sahnesi.tsx index 6fb1336..008fab8 100644 --- a/src/components/ui/acilis-sahnesi.tsx +++ b/src/components/ui/acilis-sahnesi.tsx @@ -9,9 +9,10 @@ // - Kartsız (program-ayrinti.tsx, §4.19 "kart yok"): `[data-kare]` yok, // `[data-logo]` kabındaki üç `[data-logo-kare]` belirir, kısa durur, sonra // sönerek kaybolur (scale 0.6 + opacity 0; Bilal, 7 Eki 2026) ve -// `[data-sonra]` bloklar netleşerek gelir. sahnenin kardeşi bir `[data-logo-hedef]` varsa kareler -// sönmek yerine küçülerek o yazıya (çekmece başlığı) uçar, yazı onlardan -// netleşir (Bilal, 10 Eki 2026). +// `[data-sonra]` bloklar netleşerek gelir. İçerikte `[data-logo-hedef]` +// kart alanları varsa kareler sönmek yerine aynı adlı karta uçar ve onun +// boyuna büyür; kart kareden belirir (Bilal, 11 Eki 2026; önce çekmece +// başlığına dönüşüyordu). // "Hareketi azalt"ta logo ve büyüme yok, yalnız 0,25 s solma (§6). Veri // bekleyen çekmecede (`hazir` verilmiş) sahne yalnız veri ilk geldiğinde // (false → true) oynar; önbellekli yeniden açılışta aynı 0,25 s solma @@ -58,8 +59,8 @@ const LOGO_ZAMANLARI = [ (LOGO_BELIRME + LOGO_DURUS) / LOGO_SURE, 1, ]; -// Hedefli kartsız mod: kareler sönmek yerine LOGO_UCUS süresince hedef yazıya -// uçar; uçuşun son yarısında solar, yazı o sırada netleşir. +// Hedefli kartsız mod: kareler sönmek yerine LOGO_UCUS süresince hedef karta +// uçup onun boyuna büyür; uçuşun son yarısında solar, kart o sırada belirir. const LOGO_UCUS = 0.45; const UCUS_SURE = LOGO_BELIRME + LOGO_DURUS + LOGO_UCUS; const UCUS_ZAMANLARI = [ @@ -127,9 +128,10 @@ export function logoKareStili(slot: Slot, kapBoyu = LOGO_KAP_BOYU) { * çekmece daha ekrana kaymadan oynuyor, gövde boş kalıyordu. Verilmezse * (içerik sunucudan hazır gelen çekmece) sahne her montajda oynar. * - * `data-logo-hedef`: kartsız modda logo karelerinin küçülerek dönüşeceği yazı - * (sahnenin kardeşi, ör. çekmece başlığı). Kareler yazının üç eşit dilimine - * uçar; yazı sahne başında görünmez olur, kareler varırken netleşir. + * `data-logo-hedef="sol|sag-ust|sag-alt"`: kartsız modda o logo karesinin + * dönüşeceği kart alanı (içerikte, ör. gösterge karesi). Kare kartın yerine + * uçup onun boyuna büyür; kart sahne başında görünmez olur, kare varırken + * belirir. Hedefi olmayan kare olduğu yerde söner. */ export function AcilisSahnesi({ children, @@ -224,15 +226,12 @@ export function AcilisSahnesi({ // iner ki altında boşluk kalmasın; içerik KARTSIZ_ICERIK_BASI'ndan // itibaren, sönmeyle çaprazlanarak gelir. let sonKare = 0; - // Hedef yazının kutusu (blok değil, yazının kendisi: Range). - const hedef = - kap.parentElement?.querySelector("[data-logo-hedef]") ?? null; - let hedefKutu: DOMRect | null = null; - if (hedef) { - const aralik = document.createRange(); - aralik.selectNodeContents(hedef); - hedefKutu = aralik.getBoundingClientRect(); - } + const hedefler = new Map(); + kap + .querySelectorAll("[data-logo-hedef]") + .forEach((el) => hedefler.set(el.dataset.logoHedef ?? "", el)); + // Logo kabı sıfır boya inince kartlar bu kadar yukarı kayar. + const logoBoyu = logo!.offsetHeight; logoKareleri.forEach((el) => { const slot = (el.dataset.logoKare ?? "sol") as Slot; const sira = SLOT_SIRASI.indexOf(slot); @@ -240,16 +239,31 @@ export function AcilisSahnesi({ sonKare = Math.max(sonKare, gecikme); el.style.opacity = "0"; dokunulan.push(el); - if (hedefKutu) { + const hedef = hedefler.get(slot); + if (hedef) { // Kare ile hedef aynı çekmecede: çekmece kayarken fark değişmez. const k = el.getBoundingClientRect(); - const dx = - hedefKutu.left + (hedefKutu.width * (sira + 0.5)) / 3 - (k.left + k.width / 2); - const dy = hedefKutu.top + hedefKutu.height / 2 - (k.top + k.height / 2); + const h = hedef.getBoundingClientRect(); + const dx = h.left + h.width / 2 - (k.left + k.width / 2); + const dy = h.top + h.height / 2 - logoBoyu - (k.top + k.height / 2); + const sx = h.width / k.width; + const sy = h.height / k.height; + // Ölçek köşeyi de büyütür; kartın köşesi için ters ölçekli elips. + const kose = getComputedStyle(el).borderTopLeftRadius; + const kartKose = parseFloat(getComputedStyle(hedef).borderTopLeftRadius) || 0; + const ucusBasi = gecikme + LOGO_BELIRME + LOGO_DURUS; + hedef.style.opacity = "0"; + dokunulan.push(hedef); kontroller.push( animate( el, - { x: [0, 0, 0, dx], y: [0, 0, 0, dy], scale: [0.4, 1, 1, 0.2] }, + { + x: [0, 0, 0, dx], + y: [0, 0, 0, dy], + scaleX: [0.4, 1, 1, sx], + scaleY: [0.4, 1, 1, sy], + borderRadius: [kose, kose, kose, `${kartKose / sx}px / ${kartKose / sy}px`], + }, { duration: UCUS_SURE, delay: gecikme, @@ -267,6 +281,11 @@ export function AcilisSahnesi({ ease: [GUCLU_CIKIS, "linear", "easeIn"], }, ), + animate( + hedef, + { opacity: [0, 1] }, + { duration: LOGO_UCUS * 0.5, delay: ucusBasi + LOGO_UCUS * 0.4, ease: "easeOut" }, + ), ); return; } @@ -288,22 +307,21 @@ export function AcilisSahnesi({ }); const sonmeBasi = sonKare + LOGO_SURE * LOGO_ZAMANLARI[2]; dokunulan.push(logo!); - if (hedef && hedefKutu) { - netlestir(hedef, sonmeBasi + LOGO_UCUS * 0.4, 0.4); - } const kapat = animate( logo!, { height: [logo!.offsetHeight, 0] }, - { duration: hedefKutu ? LOGO_UCUS : LOGO_SONME, delay: sonmeBasi, ease: YERLESME }, + { duration: hedefler.size > 0 ? LOGO_UCUS : LOGO_SONME, delay: sonmeBasi, ease: YERLESME }, ); kapat.then(() => { logo!.style.display = "none"; }); kontroller.push(kapat); - sonra.forEach((el, i) => - netlestir(el, KARTSIZ_ICERIK_BASI + i * KARTSIZ_BLOK_ADIMI, KARTSIZ_NETLESME), - ); + sonra.forEach((el, i) => { + // Hedef kartları taşıyan blok kendi netleşmez: kartlar karelerden belirir. + if (el.querySelector("[data-logo-hedef]")) return; + netlestir(el, KARTSIZ_ICERIK_BASI + i * KARTSIZ_BLOK_ADIMI, KARTSIZ_NETLESME); + }); return temizle; } diff --git a/src/features/katalog/components/program-ayrinti.tsx b/src/features/katalog/components/program-ayrinti.tsx index a39b0e5..914585f 100644 --- a/src/features/katalog/components/program-ayrinti.tsx +++ b/src/features/katalog/components/program-ayrinti.tsx @@ -197,15 +197,7 @@ export function ProgramAyrintiButonu({ Kapat - {/* Başlık veri gelene dek görünmez: logo kareleri küçülüp buraya - uçar, yazı onlardan netleşir (AcilisSahnesi `data-logo-hedef`). */} - + {isim} @@ -248,12 +240,13 @@ function AyrintiIcerik({ durum, veri }: { durum: Durum; veri: ProgramAyrintisi |

); } - // Sıra = AcilisSahnesi'nin `data-sonra` sırası: logo küçülerek başlığa - // dönüşür, bloklar yukarıdan aşağıya 0,05 s arayla netleşir. + // Sıra = AcilisSahnesi'nin `data-sonra` sırası: logo kareleri gösterge + // karelerine dönüşür, bloklar yukarıdan aşağıya 0,05 s arayla netleşir. return ( <> - {/* Logo kareleri: sahne sırasında görünür, küçülerek başlığa uçar; kap - sıfır boya iner. */} + {/* Logo kareleri: sahne sırasında görünür, aşağıdaki gösterge karelerine + uçup onlara dönüşür (BolumKutulari `data-logo-hedef`); kap sıfır boya + iner. */}
{LOGO_SLOTLARI.map((slot) => ( ( - + { kareRef.current[x.anahtar] = el; }} @@ -618,6 +617,7 @@ function BolumKutulari({ veri }: { veri: ProgramAyrintisi }) { — {x.baslik}, tamamını göster +
); return ( From 90181111f187027c318ac049ef8add05f8b57f7e Mon Sep 17 00:00:00 2001 From: bilalgursen Date: Sun, 11 Oct 2026 02:09:22 +0300 Subject: [PATCH 2/2] chore(surum): 2.0.1 Co-Authored-By: Claude Opus 5.5 --- package.json | 2 +- src/app/surum-notlari/page.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8971798..021ae96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kolaytercih", - "version": "2.0.0", + "version": "2.0.1", "private": true, "scripts": { "dev": "next dev", diff --git a/src/app/surum-notlari/page.tsx b/src/app/surum-notlari/page.tsx index 84f1d12..b164a25 100644 --- a/src/app/surum-notlari/page.tsx +++ b/src/app/surum-notlari/page.tsx @@ -26,6 +26,14 @@ const SURUMLER: { maddeler: string[]; arayuz?: string[]; }[] = [ + { + surum: "2.0.1", + tarih: "11 Ekim 2026", + maddeler: [], + arayuz: [ + "Program ayrıntısı açılırken logo kareleri başlığa değil, kontenjan, netler ve mezun istihdamı karelerine dönüşür.", + ], + }, { surum: "2.0.0", tarih: "11 Ekim 2026",