Skip to content

Commit ebb875a

Browse files
committed
Fix word-wrap and retriggering animation on touch (both on mobile)
1 parent df8d372 commit ebb875a

2 files changed

Lines changed: 26 additions & 15 deletions

File tree

lets-encode-logo.js

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,29 @@
156156
window.setTimeout(function () { play(); schedule(); }, 800 + idx * 850);
157157
});
158158

159-
// One trigger mechanism only: hover on devices that have it, touch on those
160-
// that don't. We never bind "click", so a tap doesn't double-fire and a
161-
// mouse click on desktop stays inert.
162-
var canHover = window.matchMedia("(hover: hover)").matches;
159+
// One trigger per input type, discriminated by pointerType rather than a
160+
// (hover: hover) media query — devices with a hovering stylus (e.g. the
161+
// Galaxy S24 Ultra's S Pen) report hover:hover even though the user taps
162+
// with a finger, which would otherwise trap touch in the hover path (plays
163+
// once, then needs a mouseleave elsewhere before it can replay).
164+
// - mouse / pen hover: replay on enter, restore the loop on leave.
165+
// - finger touch: replay on every tap, then restart the loop clock.
166+
// We never bind "click", so a tap doesn't double-fire and a desktop click
167+
// stays inert.
163168
Array.prototype.forEach.call(document.querySelectorAll("h2"), function (h2) {
164169
var gx = h2.querySelector(".gx");
165170
if (!gx) return;
166-
if (canHover) {
167-
h2.addEventListener("mouseenter", function () { gx._pause(); gx._play(); });
168-
h2.addEventListener("mouseleave", function () { gx._pause(); gx._resume(); });
169-
} else {
170-
// Touch screens: replay once on tap, then restart the auto-loop clock.
171-
h2.addEventListener("touchstart", function () {
172-
gx._pause(); gx._play(); gx._resume();
173-
}, { passive: true });
174-
}
171+
h2.addEventListener("pointerenter", function (e) {
172+
if (e.pointerType === "touch") return; // touch handled below
173+
gx._pause(); gx._play();
174+
});
175+
h2.addEventListener("pointerleave", function (e) {
176+
if (e.pointerType === "touch") return;
177+
gx._pause(); gx._resume();
178+
});
179+
h2.addEventListener("touchstart", function () {
180+
gx._pause(); gx._play(); gx._resume();
181+
}, { passive: true });
175182
});
176183
}
177184

styles.css

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ section.alt {
511511
/* clear the sticky topbar on anchor jumps so the section kicker stays visible
512512
(desktop's larger section padding already handles this) */
513513
html {
514-
scroll-padding-top: 23px;
514+
scroll-padding-top: 26px;
515515
}
516516

517517
/* burger button on the right; brand stays on the left */
@@ -608,8 +608,12 @@ section.alt {
608608
/* Keeps a word intact when a hand splits it: the .gx wrapper is inline-block,
609609
which would otherwise let the line break mid-word (e.g. "camp"/"aign"). The
610610
word's text fragments + its .gx live inside .gw so wrapping happens only at
611-
the spaces between words, never inside the hand markup. */
611+
the spaces between words, never inside the hand markup.
612+
inline-block (not merely nowrap) makes the word a firm atomic unit — Gecko
613+
(Firefox Android) still takes the wrap opportunity around the inline-block
614+
.gx inside a plain nowrap *inline*, so the word must be inline-block too. */
612615
.gw {
616+
display: inline-block;
613617
white-space: nowrap;
614618
}
615619

0 commit comments

Comments
 (0)