continue re-design
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import { ComponentProps } from "react";
|
||||
|
||||
import compressorConfig from "@/public/compressor.json";
|
||||
|
||||
interface Props extends ComponentProps<"img"> {
|
||||
src: string;
|
||||
alt: string;
|
||||
raw?: boolean;
|
||||
}
|
||||
|
||||
const BASE_SRC = "/assets/";
|
||||
const RAW_SRC = "/assets-original/";
|
||||
|
||||
export default function Image({ src, raw, ...attrs }: Props) {
|
||||
if (raw) {
|
||||
return (
|
||||
<img
|
||||
{...attrs}
|
||||
alt={attrs.alt}
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
src={RAW_SRC + src + ".png"}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<picture>
|
||||
{compressorConfig.configs
|
||||
.sort((a, b) => {
|
||||
if (a.extension === "avif" && b.extension !== "avif") return -1;
|
||||
if (b.extension === "avif" && a.extension !== "avif") return 1;
|
||||
|
||||
return a.scale - b.scale;
|
||||
})
|
||||
.map((c) => {
|
||||
return (
|
||||
<source
|
||||
key={`${c.extension}_q${c.quality}@${c.scale}x`}
|
||||
srcSet={`${BASE_SRC}${src}_q${c.quality}@${c.scale}x.${c.extension}`}
|
||||
type={`image/${c.extension}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
<img
|
||||
{...attrs}
|
||||
alt={attrs.alt}
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
src={`${BASE_SRC}${src}.png`}
|
||||
/>
|
||||
</picture>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import compressorConfig from "@/public/compressor.json";
|
||||
|
||||
const avifConfig = compressorConfig.configs.find(
|
||||
(c) => c.extension === "avif",
|
||||
)!;
|
||||
const webpConfig = compressorConfig.configs.find(
|
||||
(c) => c.extension === "webp",
|
||||
)!;
|
||||
|
||||
export async function getImageSrc(src: string) {
|
||||
const BASE_SRC = "/assets/";
|
||||
|
||||
if (await supportsEncode()) {
|
||||
return `${BASE_SRC}${src}_q${avifConfig.quality}@${avifConfig.scale}x.avif`;
|
||||
}
|
||||
|
||||
return `${BASE_SRC}${src}_q${webpConfig.quality}@${webpConfig.scale}x.webp`;
|
||||
}
|
||||
|
||||
let promise: Promise<boolean> | null = null;
|
||||
|
||||
async function supportsEncode() {
|
||||
if (promise) return promise;
|
||||
|
||||
const avifData =
|
||||
"data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUEAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABYAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgSAAAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB5tZGF0EgAKBzgADlAgIGkyCR/wAABAAACvcA==";
|
||||
|
||||
promise = fetch(avifData)
|
||||
.then((r) => r.blob())
|
||||
.then((b) => createImageBitmap(b))
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
return promise;
|
||||
}
|
||||
Reference in New Issue
Block a user