Route iOS/WebKit to transparent WebP instead of opaque VP9 WebM
WebKit (all iOS browsers + desktop Safari) plays VP9 WebM but renders its alpha as opaque black. SUPPORTS_WEBM_ALPHA now excludes iOS/Safari so those devices fall through to the animated WebP fallback, which IS transparent. Desktop Chromium/Gecko keep the WebM path.
This commit is contained in:
+14
-7
@@ -95,9 +95,17 @@
|
||||
const $ = (s) => document.querySelector(s);
|
||||
const TYPE_COLORS = { red: 0xff3b5c, yellow: 0xffc23b, blue: 0x3bb6ff };
|
||||
|
||||
// Same VP9-alpha capability check as the hunt.
|
||||
// VP9-alpha WebM transparency works on desktop Chromium/Gecko but NOT on
|
||||
// WebKit: all iOS browsers (Safari, Chrome, Firefox) and desktop Safari play
|
||||
// the WebM but render its alpha as opaque black. Those devices must fall
|
||||
// through to the animated WebP (which IS transparent), so exclude WebKit here.
|
||||
const SUPPORTS_WEBM_ALPHA = (() => {
|
||||
try {
|
||||
const ua = navigator.userAgent;
|
||||
const isIOS = /iPad|iPhone|iPod/.test(ua) ||
|
||||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); // iPadOS 13+ poses as Mac
|
||||
const isSafari = /AppleWebKit/.test(ua) && !/Chrome|Chromium|Edg|OPR/.test(ua);
|
||||
if (isIOS || isSafari) return false;
|
||||
const v = document.createElement('video');
|
||||
return !!v.canPlayType && v.canPlayType('video/webm; codecs="vp9"') !== '';
|
||||
} catch { return false; }
|
||||
@@ -215,11 +223,10 @@
|
||||
vid.muted = true; vid.loop = true; vid.playsInline = true; vid.autoplay = true; vid.preload = 'auto';
|
||||
vid.src = webm;
|
||||
const tex = new THREE.VideoTexture(vid);
|
||||
// VP9-alpha WebMs carry straight (non-premultiplied) alpha. Leave the
|
||||
// texture in the default (linear/no-color-conversion) space — forcing
|
||||
// SRGBColorSpace here makes three.js crush the alpha to black. The
|
||||
// material below blends on the video's own alpha with premultipliedAlpha
|
||||
// off so transparent regions stay see-through.
|
||||
// Desktop Chromium/Gecko only (WebKit excluded above). RGBAFormat keeps
|
||||
// the alpha channel on frame upload; no SRGB override (it can crush the
|
||||
// alpha); premultipliedAlpha off so transparent regions stay see-through.
|
||||
tex.format = THREE.RGBAFormat;
|
||||
tex.minFilter = THREE.LinearFilter; tex.magFilter = THREE.LinearFilter; tex.generateMipmaps = false;
|
||||
const mat = new THREE.MeshBasicMaterial({
|
||||
map: tex, transparent: true, side: THREE.DoubleSide,
|
||||
@@ -272,7 +279,7 @@
|
||||
const hasWebm = !!(data.webm_path || data.webm);
|
||||
const hasImg = !!(data.image_path || data.image || data.webp_path || data.webp);
|
||||
const kind = hasWebm
|
||||
? ' · WebM' + (SUPPORTS_WEBM_ALPHA ? '' : ' (no VP9-alpha fallback)')
|
||||
? (SUPPORTS_WEBM_ALPHA ? ' · WebM' : ' · WebP (WebKit fallback)')
|
||||
: hasImg ? ' · image' : ' · procedural wisp';
|
||||
$('#pv-hint').textContent = `${data.name}${kind}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user