[object Object]

← back to Voronoi Shatter

Voronoi Shatter: clamp seeds into viewport on resize + honor prefers-reduced-motion

88e9a818d859596f6b0c865fa19fc32cb779b81b · 2026-07-24 23:57:46 -0700 · Steve

- resize now clamps every seed inside the new W/H so shards can't vanish
  off-canvas when the window shrinks or a device rotates
- prefers-reduced-motion collapses grow/explode durations to ~instant and
  drops the intro-stagger, so cells still tessellate without vestibular churn

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 88e9a818d859596f6b0c865fa19fc32cb779b81b
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Jul 24 23:57:46 2026 -0700

    Voronoi Shatter: clamp seeds into viewport on resize + honor prefers-reduced-motion
    
    - resize now clamps every seed inside the new W/H so shards can't vanish
      off-canvas when the window shrinks or a device rotates
    - prefers-reduced-motion collapses grow/explode durations to ~instant and
      drops the intro-stagger, so cells still tessellate without vestibular churn
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 index.html | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/index.html b/index.html
index a32f9f2..32cdd8d 100644
--- a/index.html
+++ b/index.html
@@ -177,8 +177,13 @@
   var showSeeds = true;
   var showEdges = true;
   var sites = [];            // {x, y, phase, birth, w0, spin}
-  var ANIM_MS = 700;
-  var EXPLODE_MS = 1400;
+  // Respect the OS "reduce motion" setting: cells still tessellate, they just
+  // don't grow/explode over time (near-instant, no vestibular churn).
+  var REDUCE_MOTION = window.matchMedia &&
+    window.matchMedia("(prefers-reduced-motion: reduce)").matches;
+  var ANIM_MS = REDUCE_MOTION ? 1 : 700;
+  var EXPLODE_MS = REDUCE_MOTION ? 1 : 1400;
+  var STAGGER = REDUCE_MOTION ? 0 : 1;   // per-seed birth delay multiplier
   var MAX_SITES = 300;
   var BG = "#0b0e14";
 
@@ -532,7 +537,7 @@
     for (var i = 0; i < n; i++) {
       var x = margin + Math.random() * (W - margin * 2);
       var y = margin + Math.random() * (H - margin * 2);
-      addSite(x, y, now + i * 28); // staggered births → rippling intro shatter
+      addSite(x, y, now + i * 28 * STAGGER); // staggered births → rippling intro shatter
     }
     schedule();
   }
@@ -544,7 +549,7 @@
     for (var i = 0; i < toAdd; i++) {
       var x = margin + Math.random() * (W - margin * 2);
       var y = margin + Math.random() * (H - margin * 2);
-      addSite(x, y, now + i * 26);
+      addSite(x, y, now + i * 26 * STAGGER);
     }
     schedule();
   }
@@ -680,6 +685,13 @@
 
   window.addEventListener("resize", function () {
     resize();
+    // Keep every seed inside the new viewport so its shard can't vanish
+    // off-canvas when the window shrinks or a device rotates.
+    for (var i = 0; i < sites.length; i++) {
+      var s = sites[i];
+      if (s.x > W) s.x = W; else if (s.x < 0) s.x = 0;
+      if (s.y > H) s.y = H; else if (s.y < 0) s.y = 0;
+    }
     schedule();
   });
 

← 062b607 chore: guard centroid() against empty polygon (session close  ·  back to Voronoi Shatter  ·  polish: aria-pressed on toggles + reduced-motion CSS guard a67a3b7 →