46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
/**
|
|
* 컬러 테마 전환 — 화면 cross-fade 없이 즉시 색 swap + 색 들어간 요소들이 자기 자리에서
|
|
* entrance 재생.
|
|
*
|
|
* View Transitions API 의 화면 cross-fade 가 깜빡임으로 느껴진다는 피드백 — 호출 제거.
|
|
* 색은 즉시 바뀌고, .vt-color-changing 클래스가 잠깐 붙는 동안 색깔 사용 요소들의 keyframe
|
|
* (v5-color-refresh 계열) 만 재생되어 "색이 바뀌었다" 는 인상을 준다.
|
|
*/
|
|
|
|
type ApplyColor = (color: string) => void;
|
|
|
|
interface AnimatedColorOrigin {
|
|
x: number;
|
|
y: number;
|
|
/** 새 색상의 hex/rgb 문자열 — 클릭 burst 에 사용 */
|
|
color: string;
|
|
}
|
|
|
|
const REFRESH_DURATION_MS = 700;
|
|
|
|
export function animatedColorChange(
|
|
next: string,
|
|
applyColor: ApplyColor,
|
|
origin?: AnimatedColorOrigin,
|
|
): void {
|
|
if (origin) spawnColorBurst(origin.x, origin.y, origin.color);
|
|
|
|
const root = document.documentElement;
|
|
root.classList.add("vt-color-changing");
|
|
applyColor(next);
|
|
|
|
window.setTimeout(() => {
|
|
root.classList.remove("vt-color-changing");
|
|
}, REFRESH_DURATION_MS);
|
|
}
|
|
|
|
function spawnColorBurst(x: number, y: number, color: string) {
|
|
const burst = document.createElement("div");
|
|
burst.className = "v5-color-burst";
|
|
burst.style.left = `${x}px`;
|
|
burst.style.top = `${y}px`;
|
|
burst.style.setProperty("--burst-color", color);
|
|
document.body.appendChild(burst);
|
|
window.setTimeout(() => burst.remove(), 800);
|
|
}
|