feat: add thumbhash loading to image
Some checks failed
Deploy to SFTP Server / build (push) Failing after 1m18s
Some checks failed
Deploy to SFTP Server / build (push) Failing after 1m18s
This commit is contained in:
46
src/components/Thumbhash.astro
Normal file
46
src/components/Thumbhash.astro
Normal file
@@ -0,0 +1,46 @@
|
||||
<script>
|
||||
import { thumbHashToRGBA, rgbaToDataURL } from "thumbhash";
|
||||
|
||||
function show(img: HTMLImageElement) {
|
||||
img.style.opacity = "1";
|
||||
img.style.filter = "blur(0px)";
|
||||
setTimeout(() => {
|
||||
img.parentNode.style.background = "";
|
||||
}, 600);
|
||||
}
|
||||
|
||||
document.querySelectorAll("[data-thumbhash]").forEach((entry) => {
|
||||
const parent = entry?.parentNode as HTMLPictureElement;
|
||||
const img = entry as HTMLImageElement;
|
||||
|
||||
if (parent?.nodeName !== "PICTURE") return;
|
||||
|
||||
const hash = img.getAttribute("data-thumbhash");
|
||||
if (!hash) return;
|
||||
|
||||
const decodedString = atob(hash);
|
||||
|
||||
// Create Uint8Array from decoded string
|
||||
const buffer = new Uint8Array(decodedString.length);
|
||||
for (let i = 0; i < decodedString.length; i++) {
|
||||
buffer[i] = decodedString.charCodeAt(i);
|
||||
}
|
||||
|
||||
const image = thumbHashToRGBA(buffer);
|
||||
const dataURL = rgbaToDataURL(image.w, image.h, image.rgba);
|
||||
|
||||
parent.style.background = `url(${dataURL})`;
|
||||
parent.style.backgroundSize = "cover";
|
||||
|
||||
img.style.opacity = "0";
|
||||
img.style.filter = "blur(5px)";
|
||||
img.style.transition = "opacity 0.6s ease, filter 0.8s ease";
|
||||
|
||||
const sources = parent.querySelectorAll("source");
|
||||
|
||||
img.onload = () => show(img);
|
||||
for (const source of sources) {
|
||||
source.addEventListener("load", () => show(img));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user