Skip to content

Commit a5d5c1f

Browse files
committed
feat: scale svgs
1 parent 7c62f90 commit a5d5c1f

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/pages/badges/[category]/[slug]/[size].[format].ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const formats: Record<Format, `image/${string}`> = {
1414
webp: "image/webp",
1515
}
1616

17+
const svgRegex = /<svg width="(\d+)" height="(\d+)" [\S\d\s]*/
18+
1719
export const GET: APIRoute = async ({ params }) => {
1820
const format = params["format"] as Format;
1921
let category = params["category"] as Category;
@@ -31,12 +33,13 @@ export const GET: APIRoute = async ({ params }) => {
3133
}
3234
}
3335

36+
const targetHeight = heights[size];
3437

3538
const img = await readFile(`src/assets/${category}/${slug}/${size}.svg`);
3639

3740
const isSVG = format === "svg";
3841
if(!isSVG) {
39-
const formatted = sharp(img).resize({ height: heights[size] });
42+
const formatted = sharp(img).resize({ height: targetHeight });
4043

4144
// Set background to white if image doesn't support transparency
4245
if(["jpeg", "jpg"].includes(format)) formatted.flatten({ background: "#FFFFFF" })
@@ -45,7 +48,19 @@ export const GET: APIRoute = async ({ params }) => {
4548
return new Response(await formatted.toFormat(format).toBuffer(), { headers: { "Content-Type": formats[format] }});
4649
}
4750

48-
return new Response(img, { headers: { "Content-Type": formats[format] }});
51+
const svg = img.toString();
52+
53+
const [_, width, height] = svgRegex.exec(svg) as string[];
54+
if(!width || !height) return new Response(img, { headers: { "Content-Type": formats[format] }});
55+
56+
const widthInt = Number.parseInt(width, 10);
57+
const heightInt = Number.parseInt(height, 10);
58+
59+
const scaleFactor = targetHeight / heightInt;
60+
if(Number.isNaN(scaleFactor)) throw new Error("Scale factor is NaN");
61+
62+
const newWidth = widthInt * scaleFactor;
63+
return new Response(svg.replace(/<svg width="(\d+)" height="(\d+)"/, `<svg width="${newWidth}" height="${targetHeight}"`), { headers: { "Content-Type": formats[format] }});
4964
}
5065

5166
export const prerender = true;

0 commit comments

Comments
 (0)