diff --git a/src/lib/background.ts b/src/lib/background.ts
index 6beb9a8..5fbba65 100644
--- a/src/lib/background.ts
+++ b/src/lib/background.ts
@@ -1,8 +1,6 @@
-const STORAGE_KEY = "background-motion-preference";
const MOTION_QUERY = "(prefers-reduced-motion: reduce)";
const STILL_STEPS = 5;
-type MotionPreference = "auto" | "off" | "on";
type BackgroundMode = "animated" | "still" | "failed";
interface BackgroundActions {
@@ -11,23 +9,7 @@ interface BackgroundActions {
renderStill: (steps: number) => void;
}
-function readPreference(): MotionPreference {
- const stored = window.localStorage.getItem(STORAGE_KEY);
- return stored === "off" || stored === "on" || stored === "auto"
- ? stored
- : "auto";
-}
-
-function writePreference(preference: MotionPreference) {
- window.localStorage.setItem(STORAGE_KEY, preference);
-}
-
-function getMode(
- preference: MotionPreference,
- reducedMotion: boolean,
-): BackgroundMode {
- if (preference === "on") return "animated";
- if (preference === "off") return "still";
+function getMode(reducedMotion: boolean): BackgroundMode {
return reducedMotion ? "still" : "animated";
}
@@ -39,46 +21,22 @@ function applyCanvasState(mode: BackgroundMode) {
}
}
-function updateControls(
- preference: MotionPreference,
- mode: BackgroundMode,
- reducedMotion: boolean,
-) {
- const button = document.getElementById(
- "background-toggle",
- ) as HTMLButtonElement | null;
- const status = document.getElementById("background-status");
- if (!button || !status) return;
-
- button.textContent = `motion ${preference}`;
-
- if (mode === "failed") {
- status.textContent = "background unavailable";
- return;
- }
-
- if (mode === "still") {
- status.textContent =
- preference === "auto" && reducedMotion
- ? "still frame"
- : "background still";
- return;
- }
-
- status.textContent = "background live";
-}
-
export function initBackgroundControls(actions: BackgroundActions) {
const media = window.matchMedia(MOTION_QUERY);
- let preference = readPreference();
- let mode: BackgroundMode = getMode(preference, media.matches);
+ let mode: BackgroundMode = getMode(media.matches);
+ let failed = false;
- const applyMode = () => {
- mode = getMode(preference, media.matches);
+ const applyMode = (restartAnimation = false) => {
+ if (failed) return;
+
+ mode = getMode(media.matches);
applyCanvasState(mode);
- updateControls(preference, mode, media.matches);
if (mode === "animated") {
+ if (restartAnimation) {
+ actions.stop();
+ }
+
actions.start();
return;
}
@@ -87,29 +45,34 @@ export function initBackgroundControls(actions: BackgroundActions) {
actions.renderStill(STILL_STEPS);
};
- const button = document.getElementById(
- "background-toggle",
- ) as HTMLButtonElement | null;
+ const restartAnimation = () => {
+ if (document.visibilityState === "hidden" || media.matches) {
+ return;
+ }
- button?.addEventListener("click", () => {
- preference =
- preference === "auto" ? "off" : preference === "off" ? "on" : "auto";
- writePreference(preference);
- applyMode();
- });
+ applyMode(true);
+ };
media.addEventListener("change", () => {
applyMode();
});
+ document.addEventListener("visibilitychange", () => {
+ restartAnimation();
+ });
+
+ window.addEventListener("pageshow", () => {
+ restartAnimation();
+ });
+
return {
applyInitialMode() {
applyMode();
},
setFailed() {
+ failed = true;
mode = "failed";
applyCanvasState(mode);
- updateControls(preference, mode, media.matches);
},
};
}
diff --git a/src/lib/site.ts b/src/lib/site.ts
index a142232..a0f578a 100644
--- a/src/lib/site.ts
+++ b/src/lib/site.ts
@@ -38,9 +38,6 @@ export function renderFooter() {
|
ssh
|
-
-
- |
${mirror.label}
`;
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 8abbd95..97e0f70 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -352,10 +352,6 @@ a[aria-current="page"] {
color: var(--dark-gray);
}
-#background-status {
- margin-top: 0;
-}
-
.sr-only {
position: absolute;
width: 1px;