mirror of
https://github.com/10h30/blog-balodeplao.git
synced 2026-05-12 15:21:15 +09:00
refactor: simplify Picture component and remove unused R2 image handling, add figcaption
This commit is contained in:
@@ -1,60 +1,21 @@
|
|||||||
---
|
---
|
||||||
import { R2_BASE } from "@/config/r2.mjs";
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
src: string;
|
src: string;
|
||||||
alt: string;
|
alt: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
sizes?: string;
|
|
||||||
fetchpriority?: "high" | "low" | "auto";
|
fetchpriority?: "high" | "low" | "auto";
|
||||||
loading?: "lazy" | "eager";
|
loading?: "lazy" | "eager";
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { src, alt, class: className, fetchpriority, loading } = Astro.props;
|
||||||
src,
|
|
||||||
alt,
|
|
||||||
class: className,
|
|
||||||
sizes = "(max-width: 640px) 100vw, (max-width: 1024px) 80vw, 1200px",
|
|
||||||
fetchpriority,
|
|
||||||
loading,
|
|
||||||
} = Astro.props;
|
|
||||||
|
|
||||||
const WIDTHS = [480, 800, 1200];
|
|
||||||
|
|
||||||
const isR2 = src.includes(R2_BASE.replace("https://", ""));
|
|
||||||
|
|
||||||
function buildTransformUrl(src: string, width: number) {
|
|
||||||
const path = src.replace(R2_BASE, "");
|
|
||||||
return `${R2_BASE}/cdn-cgi/image/width=${width},format=auto,onerror=redirect${path}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcset = WIDTHS.map((w) => `${buildTransformUrl(src, w)} ${w}w`).join(
|
|
||||||
", ",
|
|
||||||
);
|
|
||||||
const defaultSrc = isR2 ? buildTransformUrl(src, 800) : src;
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{
|
<picture>
|
||||||
isR2 ? (
|
<img
|
||||||
<picture>
|
src={src}
|
||||||
<source type="image/webp" srcset={srcset} sizes={sizes} />
|
alt={alt}
|
||||||
<img
|
class={className}
|
||||||
src={defaultSrc}
|
fetchpriority={fetchpriority}
|
||||||
srcset={srcset}
|
loading={loading}
|
||||||
sizes={sizes}
|
/>
|
||||||
alt={alt}
|
</picture>
|
||||||
class={className}
|
|
||||||
fetchpriority={fetchpriority}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
</picture>
|
|
||||||
) : (
|
|
||||||
<img
|
|
||||||
src={src}
|
|
||||||
alt={alt}
|
|
||||||
class={className}
|
|
||||||
fetchpriority={fetchpriority}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,14 +1,4 @@
|
|||||||
import { visit } from "unist-util-visit";
|
import { visit } from "unist-util-visit";
|
||||||
import { R2_BASE } from "../config/r2.mjs";
|
|
||||||
|
|
||||||
const WIDTHS = [480, 800, 1200];
|
|
||||||
const SIZES = "(max-width: 640px) 100vw, (max-width: 1024px) 80vw, 1200px";
|
|
||||||
|
|
||||||
function buildTransformUrl(src, width) {
|
|
||||||
// Extract path từ full URL
|
|
||||||
const path = src.replace(R2_BASE, "");
|
|
||||||
return `${R2_BASE}/cdn-cgi/image/width=${width},format=auto,onerror=redirect${path}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function rehypePictureWebp() {
|
export function rehypePictureWebp() {
|
||||||
return (tree) => {
|
return (tree) => {
|
||||||
@@ -16,46 +6,41 @@ export function rehypePictureWebp() {
|
|||||||
if (node.tagName !== "img") return;
|
if (node.tagName !== "img") return;
|
||||||
if (!parent || index == null) return;
|
if (!parent || index == null) return;
|
||||||
|
|
||||||
const src = node.properties?.src || "";
|
const alt = node.properties?.alt || node.alt || "";
|
||||||
|
const pictureNode = {
|
||||||
// Chỉ xử lý ảnh từ R2
|
|
||||||
if (!src.startsWith(R2_BASE)) return;
|
|
||||||
|
|
||||||
// Tạo srcset với nhiều width
|
|
||||||
const srcset = WIDTHS.map(
|
|
||||||
(w) => `${buildTransformUrl(src, w)} ${w}w`,
|
|
||||||
).join(", ");
|
|
||||||
|
|
||||||
const defaultSrc = buildTransformUrl(src, 800);
|
|
||||||
|
|
||||||
parent.children[index] = {
|
|
||||||
type: "element",
|
type: "element",
|
||||||
tagName: "picture",
|
tagName: "picture",
|
||||||
properties: {},
|
properties: {},
|
||||||
children: [
|
children: [
|
||||||
{
|
|
||||||
type: "element",
|
|
||||||
tagName: "source",
|
|
||||||
properties: {
|
|
||||||
type: "image/webp",
|
|
||||||
srcSet: srcset,
|
|
||||||
sizes: SIZES,
|
|
||||||
},
|
|
||||||
children: [],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
...node,
|
...node,
|
||||||
properties: {
|
properties: {
|
||||||
...node.properties,
|
...node.properties,
|
||||||
src: defaultSrc,
|
|
||||||
srcSet: srcset,
|
|
||||||
sizes: SIZES,
|
|
||||||
loading: "lazy",
|
loading: "lazy",
|
||||||
decoding: "async",
|
decoding: "async",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (alt) {
|
||||||
|
parent.children[index] = {
|
||||||
|
type: "element",
|
||||||
|
tagName: "figure",
|
||||||
|
properties: {},
|
||||||
|
children: [
|
||||||
|
pictureNode,
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
tagName: "figcaption",
|
||||||
|
properties: {},
|
||||||
|
children: [{ type: "text", value: alt }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
parent.children[index] = pictureNode;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user