Keep WebP animating on iOS by attaching the source img to the DOM

iOS pauses animation on a detached <img>, so the CanvasTexture sampled a
frozen frame. Attach the img hidden off-screen (opacity 0.01) so WebKit
keeps advancing the WebP; remove it on clear.
This commit is contained in:
2026-06-22 09:53:36 +10:00
parent 4cf8ec07a4
commit 25832dd58f
+5
View File
@@ -253,6 +253,10 @@
// the texture animates and transparency is preserved. // the texture animates and transparency is preserved.
const img = document.createElement('img'); const img = document.createElement('img');
img.crossOrigin = 'anonymous'; img.src = image; img.crossOrigin = 'anonymous'; img.src = image;
// iOS pauses animation on a detached <img>, so attach it hidden off-screen
// to keep the WebP advancing. We sample its current frame into the canvas.
img.style.cssText = 'position:fixed;left:-99999px;top:0;width:64px;height:64px;pointer-events:none;opacity:0.01;';
document.body.appendChild(img);
const cnv = document.createElement('canvas'); const cnv = document.createElement('canvas');
cnv.width = 256; cnv.height = 256; cnv.width = 256; cnv.height = 256;
const ctx = cnv.getContext('2d'); const ctx = cnv.getContext('2d');
@@ -301,6 +305,7 @@
function clearGhost() { function clearGhost() {
if (!current) return; if (!current) return;
if (current.userData.vidEl) { try { current.userData.vidEl.pause(); current.userData.vidEl.src = ''; } catch {} } if (current.userData.vidEl) { try { current.userData.vidEl.pause(); current.userData.vidEl.src = ''; } catch {} }
if (current.userData.animImg) { try { current.userData.animImg.remove(); } catch {} }
scene.remove(current); scene.remove(current);
current = null; current = null;
} }