fix(tema): logo dönüşümü hover döngüsünden öncelikli

İmleç logonun üzerindeyken tema değişirse döngü kesilir, kareler o an
neredeyse oradan güneşe/aya geçer; biçim bitince imleç hâlâ üzerindeyse
hover döngüsü yerinden yeniden başlar. DESIGN §2.3 notu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-10-09 00:33:12 +03:00
parent 316f1dafa0
commit 50c2f7f292
2 changed files with 36 additions and 18 deletions

View File

@@ -268,19 +268,11 @@ export function AnimasyonluMark({
);
};
const ayarla = (yeni: Varyant | null, cevik = false) => {
if (yeni === hedef) return;
hedef = yeni;
// Hover döngüsü biçimin üstüne binmesin: güneş/ay yarıda kesilir.
if (yeni !== null) {
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))
/** `yeni` döngüsünü, süren dönüş ve tema biçimi bitince yerinden başlatır. */
const donguyuSiraya = (yeni: Varyant) => {
// Kareler hâlâ yerine dönüyorsa (ya da güneş/ay oynuyorsa) bitmesi
// beklenir; döngü hep yerinden başlar, sıçrama olmaz.
Promise.all([...donus, ...sekil].map((a) => a.finished))
.then(() => {
if (sokuldu || hedef !== yeni || aktif !== null) return;
dongu = kareler.flatMap((el, i) => donguyuBaslat(el, i, yeni));
@@ -289,16 +281,39 @@ export function AnimasyonluMark({
.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
* 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
* çizilir (zemin şeffaf, renk iç gölgede): arkadaki zemin ne olursa olsun
* doğru görünür.
*/
const temaSekli = (koyu: boolean) => {
if (aktif !== null || hedef !== null || azHareket.matches) return;
sekil.forEach((a) => a.cancel());
if (azHareket.matches) return;
// 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) => {
const k = KARELER[i];
const ev = {
@@ -312,7 +327,7 @@ export function AnimasyonluMark({
const animasyonlar = [
el.animate(
[
{ ...ev, easing: DONUS },
{ ...anlik[i], easing: DONUS },
{ ...bicim, easing: "linear" },
{ ...bicim, easing: YERLES },
ev,
@@ -340,6 +355,8 @@ export function AnimasyonluMark({
}
return animasyonlar;
});
// İmleç hâlâ üzerindeyse hover döngüsü biçimden sonra sürer.
if (hedef !== null) donguyuSiraya(hedef);
};
const kontrol = { ayarla, temaSekli };