This commit is contained in:
seb
2026-09-27 16:19:08 +02:00
parent 559307675c
commit 0f875f347e
16 changed files with 1768 additions and 47 deletions

View File

@@ -2,19 +2,34 @@ import { useEffect, useRef } from 'react';
import Box from '@mui/material/Box';
import { thumbHashToRGBA } from 'thumbhash';
function decodeThumbHash(thumbHash) {
const bytes = Uint8Array.from(atob(thumbHash), (c) => c.charCodeAt(0));
return thumbHashToRGBA(bytes);
export function decodeThumbHash(thumbHash) {
if (!thumbHash || typeof thumbHash !== 'string') return null;
try {
const bytes = Uint8Array.from(atob(thumbHash), (c) => c.charCodeAt(0));
return thumbHashToRGBA(bytes);
} catch (err) {
console.warn('[ThumbHashImage] decode failed:', err);
return null;
}
}
function paintThumbHash(canvas, thumbHash) {
export function getThumbHashDimensions(thumbHash) {
const decoded = decodeThumbHash(thumbHash);
if (!decoded) return null;
return { w: decoded.w, h: decoded.h };
}
function paintThumbHash(canvas, thumbHash, explicitWidth, explicitHeight) {
const parent = canvas.parentElement;
if (!parent) return;
const rect = parent ? parent.getBoundingClientRect() : null;
const width = explicitWidth || rect?.width;
const height = explicitHeight || rect?.height;
if (!width || !height) return;
const { width, height } = parent.getBoundingClientRect();
if (width === 0 || height === 0) return;
const decoded = decodeThumbHash(thumbHash);
if (!decoded) return;
const { w, h, rgba } = decoded;
const { w, h, rgba } = decodeThumbHash(thumbHash);
const src = document.createElement('canvas');
src.width = w;
src.height = h;
@@ -34,24 +49,24 @@ function paintThumbHash(canvas, thumbHash) {
ctx.drawImage(src, 0, 0, canvas.width, canvas.height);
}
export default function ThumbHashImage({ thumbHash, sx }) {
export default function ThumbHashImage({ thumbHash, width, height, sx }) {
const canvasRef = useRef(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas || !thumbHash) return;
paintThumbHash(canvas, thumbHash);
paintThumbHash(canvas, thumbHash, width, height);
const parent = canvas.parentElement;
if (!parent || typeof ResizeObserver === 'undefined') return undefined;
const observer = new ResizeObserver(() => {
paintThumbHash(canvas, thumbHash);
paintThumbHash(canvas, thumbHash, width, height);
});
observer.observe(parent);
return () => observer.disconnect();
}, [thumbHash]);
}, [thumbHash, width, height]);
return (
<Box