mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
169 lines
5.0 KiB
TypeScript
169 lines
5.0 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
import satori from "satori";
|
|
import sharp from "sharp";
|
|
import { fontData, experimental_getFontFileURL } from "astro:assets";
|
|
import { getFontPathByWeight } from "@/utils/getFontPathByWeight";
|
|
import config from "@/config";
|
|
|
|
export const GET: APIRoute = async context => {
|
|
const fonts = fontData["--font-noto-serif-sc"];
|
|
const regularFontPath = getFontPathByWeight(fonts, 400);
|
|
const boldFontPath = getFontPathByWeight(fonts, 700);
|
|
|
|
if (regularFontPath === undefined || boldFontPath === undefined) {
|
|
throw new Error("Cannot find the font path.");
|
|
}
|
|
|
|
const [regularData, boldData] = await Promise.all([
|
|
fetch(experimental_getFontFileURL(regularFontPath, context.url)).then(res =>
|
|
res.arrayBuffer()
|
|
),
|
|
fetch(experimental_getFontFileURL(boldFontPath, context.url)).then(res =>
|
|
res.arrayBuffer()
|
|
),
|
|
]);
|
|
|
|
const svg = await satori(
|
|
{
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
background: "#fefbfb",
|
|
width: "100%",
|
|
height: "100%",
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
fontFamily: "Noto Serif SC",
|
|
},
|
|
children: [
|
|
{
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
position: "absolute",
|
|
top: "-1px",
|
|
right: "-1px",
|
|
border: "4px solid #000",
|
|
background: "#ecebeb",
|
|
opacity: "0.9",
|
|
borderRadius: "4px",
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
margin: "2.5rem",
|
|
width: "88%",
|
|
height: "80%",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
border: "4px solid #000",
|
|
background: "#fefbfb",
|
|
borderRadius: "4px",
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
margin: "2rem",
|
|
width: "88%",
|
|
height: "80%",
|
|
},
|
|
children: {
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "space-between",
|
|
margin: "20px",
|
|
width: "90%",
|
|
height: "90%",
|
|
},
|
|
children: [
|
|
{
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
height: "90%",
|
|
maxHeight: "90%",
|
|
overflow: "hidden",
|
|
textAlign: "center",
|
|
},
|
|
children: [
|
|
{
|
|
type: "p",
|
|
props: {
|
|
style: { fontSize: 72, fontWeight: "bold" },
|
|
children: config.site.title,
|
|
},
|
|
},
|
|
{
|
|
type: "p",
|
|
props: {
|
|
style: { fontSize: 28 },
|
|
children: config.site.description,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
type: "div",
|
|
props: {
|
|
style: {
|
|
display: "flex",
|
|
justifyContent: "flex-end",
|
|
width: "100%",
|
|
marginBottom: "8px",
|
|
fontSize: 28,
|
|
},
|
|
children: {
|
|
type: "span",
|
|
props: {
|
|
style: { overflow: "hidden", fontWeight: "bold" },
|
|
children: new URL(config.site.url).hostname,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
{
|
|
width: 1200,
|
|
height: 630,
|
|
embedFont: true,
|
|
fonts: [
|
|
{
|
|
name: "Noto Serif SC",
|
|
data: regularData,
|
|
weight: 400,
|
|
style: "normal",
|
|
},
|
|
{
|
|
name: "Noto Serif SC",
|
|
data: boldData,
|
|
weight: 700,
|
|
style: "normal",
|
|
},
|
|
],
|
|
}
|
|
);
|
|
|
|
const pngBuffer = await sharp(Buffer.from(svg)).png().toBuffer();
|
|
|
|
return new Response(new Uint8Array(pngBuffer), {
|
|
headers: { "Content-Type": "image/png" },
|
|
});
|
|
};
|