24 lines
1.6 KiB
TypeScript
24 lines
1.6 KiB
TypeScript
export type FxState = 'wait' | 'fade' | 'ready' | 'error'
|
|
|
|
let alternative: (src: string) => string | null = () => null
|
|
export function configureImageFallback(find: (src: string) => string | null): void { alternative = find }
|
|
export const imageFallback = (src: string): string | null => alternative(src)
|
|
|
|
export function reveal(img: HTMLImageElement, instant?: boolean): void {
|
|
if (img.getAttribute('data-fx') !== 'wait' || !img.complete) return
|
|
const src = img.currentSrc || img.src
|
|
const set = (state: string) => {
|
|
if (img.getAttribute('data-fx') === 'wait' && (img.currentSrc || img.src) === src) img.setAttribute('data-fx', state)
|
|
}
|
|
if (!img.naturalWidth) { set('error'); return }
|
|
if (instant) { set('ready'); return }
|
|
if (typeof img.decode !== 'function') { set('fade'); return }
|
|
img.decode().then(() => set('fade'), () => set(img.naturalWidth ? 'fade' : 'error'))
|
|
}
|
|
|
|
export const FX_IMAGE_SCRIPT = `(function(){var r=${reveal.toString()};` +
|
|
`var p=/(\\/game\\/[^?#\\s]+)\\.png(?=[?#\\s]|$)/g;` +
|
|
`function w(t){if(t.getAttribute('data-webp-tried'))return false;var s=t.getAttribute('src')||'';if(!/\\/game\\/[^?#]+\\.png/.test(s))return false;` +
|
|
`t.setAttribute('data-webp-tried','1');var ss=t.getAttribute('srcset');if(ss)t.setAttribute('srcset',ss.replace(p,'$1.webp'));t.setAttribute('src',s.replace(p,'$1.webp'));return true}` +
|
|
`function h(e){var t=e.target;if(!t||t.tagName!=='IMG')return;if(e.type==='error'&&w(t))return;if(t.hasAttribute('data-fx'))r(t)}` +
|
|
`document.addEventListener('load',h,true);document.addEventListener('error',h,true)})()`
|