v1-beta-tema #9

Merged
bilal merged 19 commits from v1-beta-tema into main 2026-10-09 02:30:44 +03:00
2 changed files with 36 additions and 18 deletions
Showing only changes of commit 50c2f7f292 - Show all commits

View File

@@ -138,7 +138,8 @@ tema header'daki logodan **yumuşak bir halka** gibi açılır: kenarı keskin d
tüylü (ışık yayılır gibi), 1100 ms, yumuşak kalkıp yumuşak durur. Aynı anda logonun kareleri tüylü (ışık yayılır gibi), 1100 ms, yumuşak kalkıp yumuşak durur. Aynı anda logonun kareleri
yeni temanın biçimine dönüşür: koyuya geçişte şeftali kare hilale, mavi ve turuncu kareler iki yeni temanın biçimine dönüşür: koyuya geçişte şeftali kare hilale, mavi ve turuncu kareler iki
yıldıza; açığa geçişte turuncu kare güneşe, şeftali kare halesine. Kısa bir an durur, yeniden yıldıza; açığa geçişte turuncu kare güneşe, şeftali kare halesine. Kısa bir an durur, yeniden
logoya toplanır (`animasyonlu-mark.tsx` `temaSekli`, 1,7 sn; yalnız header'daki logo). Tema logoya toplanır (`animasyonlu-mark.tsx` `temaSekli`, 1,7 sn; yalnız header'daki logo; hover döngüsünden
önceliklidir, biçim bitince imleç üzerindeyse döngü kaldığı yerden değil yerinden sürer). Tema
seçicinin ikonları aynı biçimlerin durağan hâlidir (`tema-ikonu.tsx`: güneş, ay, Sistem için seçicinin ikonları aynı biçimlerin durağan hâlidir (`tema-ikonu.tsx`: güneş, ay, Sistem için
logonun üç karesi); burada lucide ikonu kullanılmaz. View Transitions + radyal degrade logonun üç karesi); burada lucide ikonu kullanılmaz. View Transitions + radyal degrade
maskesi: `src/lib/tema-gecisi.ts`, `globals.css` `.kt-tema-gecis`; hareket azaltılmışsa düz maskesi: `src/lib/tema-gecisi.ts`, `globals.css` `.kt-tema-gecis`; hareket azaltılmışsa düz

View File

@@ -268,19 +268,11 @@ export function AnimasyonluMark({
); );
}; };
const ayarla = (yeni: Varyant | null, cevik = false) => { /** `yeni` döngüsünü, süren dönüş ve tema biçimi bitince yerinden başlatır. */
if (yeni === hedef) return; const donguyuSiraya = (yeni: Varyant) => {
hedef = yeni; // Kareler hâlâ yerine dönüyorsa (ya da güneş/ay oynuyorsa) bitmesi
// Hover döngüsü biçimin üstüne binmesin: güneş/ay yarıda kesilir. // beklenir; döngü hep yerinden başlar, sıçrama olmaz.
if (yeni !== null) { Promise.all([...donus, ...sekil].map((a) => a.finished))
sekil.forEach((a) => a.cancel());
sekil = [];
}
if (aktif !== null) yerles(cevik);
if (yeni === null || azHareket.matches) return;
// Kareler hâlâ yerine dönüyorsa dönüşün bitmesi beklenir; döngü hep
// yerinden başlar, sıçrama olmaz.
Promise.all(donus.map((a) => a.finished))
.then(() => { .then(() => {
if (sokuldu || hedef !== yeni || aktif !== null) return; if (sokuldu || hedef !== yeni || aktif !== null) return;
dongu = kareler.flatMap((el, i) => donguyuBaslat(el, i, yeni)); dongu = kareler.flatMap((el, i) => donguyuBaslat(el, i, yeni));
@@ -289,16 +281,39 @@ export function AnimasyonluMark({
.catch(() => {}); .catch(() => {});
}; };
const ayarla = (yeni: Varyant | null, cevik = false) => {
if (yeni === hedef) return;
hedef = yeni;
if (aktif !== null) yerles(cevik);
if (yeni === null || azHareket.matches) return;
donguyuSiraya(yeni);
};
/** /**
* Tema geçişi biçimi: kareler güneşe ya da aya dönüşür, durur, logoya * Tema geçişi biçimi: kareler güneşe ya da aya dönüşür, durur, logoya
* döner. Döngü oynarken (hover) ya da hareket azaltılmışken çalışmaz. * döner. Hover döngüsünden önceliklidir: döngü oynuyorsa kesilir, kareler
* o an neredeyse oradan biçime geçer; biçim bitince imleç hâlâ
* üzerindeyse döngü yerinden yeniden başlar. Hareket azaltılmışsa çalışmaz.
* Hilal, kareyi kesen ikinci bir şekille değil karenin kendi iç gölgesiyle * Hilal, kareyi kesen ikinci bir şekille değil karenin kendi iç gölgesiyle
* çizilir (zemin şeffaf, renk iç gölgede): arkadaki zemin ne olursa olsun * çizilir (zemin şeffaf, renk iç gölgede): arkadaki zemin ne olursa olsun
* doğru görünür. * doğru görünür.
*/ */
const temaSekli = (koyu: boolean) => { const temaSekli = (koyu: boolean) => {
if (aktif !== null || hedef !== null || azHareket.matches) return; if (azHareket.matches) return;
sekil.forEach((a) => a.cancel()); // Karelerin o anki hâli: döngü ya da önceki biçim yarıdaysa oradan çıkılır.
const anlik = kareler.map((el) => {
const cs = getComputedStyle(el);
return {
translate: cs.translate,
scale: cs.scale,
opacity: cs.opacity,
borderRadius: cs.borderRadius,
};
});
[...dongu, ...donus, ...sekil].forEach((a) => a.cancel());
dongu = [];
donus = [];
aktif = null;
sekil = kareler.flatMap((el, i) => { sekil = kareler.flatMap((el, i) => {
const k = KARELER[i]; const k = KARELER[i];
const ev = { const ev = {
@@ -312,7 +327,7 @@ export function AnimasyonluMark({
const animasyonlar = [ const animasyonlar = [
el.animate( el.animate(
[ [
{ ...ev, easing: DONUS }, { ...anlik[i], easing: DONUS },
{ ...bicim, easing: "linear" }, { ...bicim, easing: "linear" },
{ ...bicim, easing: YERLES }, { ...bicim, easing: YERLES },
ev, ev,
@@ -340,6 +355,8 @@ export function AnimasyonluMark({
} }
return animasyonlar; return animasyonlar;
}); });
// İmleç hâlâ üzerindeyse hover döngüsü biçimden sonra sürer.
if (hedef !== null) donguyuSiraya(hedef);
}; };
const kontrol = { ayarla, temaSekli }; const kontrol = { ayarla, temaSekli };