Skip to content

Commit

Permalink
Add support for customizing icon size
Browse files Browse the repository at this point in the history
  • Loading branch information
LitoMore committed Aug 26, 2024
1 parent 0656f30 commit 7e6f8a1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Optional. It's used for dark mode and has the same function as `color`. The [CSS

Optional. The icon is placed in a square viewBox by default. Use the query parameter `viewbox=auto` to adjust the viewBox to the same aspect ratio as the shape.

#### `size`

Optional. It's used for customizing the icon size. Icon will be scaled with its original aspect ratio.

### Examples

- <img height="14" src="https://cdn.simpleicons.org/simpleicons/111/eee"/> - https://cdn.simpleicons.org/simpleicons
Expand Down
4 changes: 2 additions & 2 deletions source/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ router.get("/:iconSlug/:color?/:darkModeColor?", (ctx) => {
cacheForSevenDays(ctx);
const { iconSlug, color, darkModeColor } = ctx.params;
const viewbox = ctx.request.url.searchParams.get("viewbox");
const size = ctx.request.url.searchParams.get("size");
const icon = getSimpleIcon(iconSlug);

if (icon) {
const iconSvg = getIconSvg(icon, color, darkModeColor, viewbox);
const iconSvg = getIconSvg(icon, color, darkModeColor, viewbox, size);
ctx.response.headers.set("Content-Type", "image/svg+xml");
ctx.response.body = iconSvg;
return;
Expand Down
28 changes: 26 additions & 2 deletions source/icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,19 @@ export const resetIconPosition = (path, iconWidth, iconHeight) => {
return { path: pathReset, betterViewboxWidth };
};

export const getIconSvg = (icon, color = "", darkModeColor = "", viewbox) => {
export const getIconSvg = (
icon,
color = "",
darkModeColor = "",
viewbox,
size,
) => {
const hex = normalizeColor(color) || `#${icon.hex}`;
const darkModeHex = normalizeColor(darkModeColor) || `#${icon.hex}`;
let iconSvg = icon.svg;

if (viewbox === "auto") {
const { width: iconWidth, height: iconHeight } = getIconSize(icon.path);

const { path, betterViewboxWidth } = resetIconPosition(
icon.path,
iconWidth,
Expand All @@ -68,6 +73,25 @@ export const getIconSvg = (icon, color = "", darkModeColor = "", viewbox) => {
.replace(/<path d=".*"\/>/, `<path d="${path}"/>`);
}

const iconSize = parseInt(size, 10);
if (iconSize && iconSize > 0) {
const sizePattern = /viewBox="0 0 (?<width>\d+) (?<height>\d+)"/;
const sizeMatch = sizePattern.exec(iconSvg);
const width = sizeMatch?.groups?.width;
const height = sizeMatch?.groups?.height;
if (Number(width) && Number(height)) {
const maxScale = (2 ** 14 - 1) / 24;
const minScale = 3 / 24;
const scale = Math.max(Math.min(maxScale, iconSize / 24), minScale);
const iconWidth = Math.round(width * scale);
const iconHeight = Math.round(height * scale);
iconSvg = iconSvg.replace(
"<svg ",
`<svg width="${iconWidth}" height="${iconHeight}" `,
);
}
}

if (darkModeColor && hex !== darkModeHex) {
return iconSvg.replace(
"<path ",
Expand Down

0 comments on commit 7e6f8a1

Please sign in to comment.