static badge positions working, updae optionals field of the README

This commit is contained in:
2025-07-09 12:38:10 +02:00
parent b1485ba3d4
commit ec9359fb0a
2 changed files with 95 additions and 47 deletions
+9 -9
View File
@@ -6,15 +6,15 @@ BadgeDex
Az alábbi paraméterekkel szabályozhatod a `/badge` végpont működését: Az alábbi paraméterekkel szabályozhatod a `/badge` végpont működését:
| Paraméter | Alapértelmezett érték | Leírás | Példa értékek | | Paraméter | Kötelező | Alapértelmezett érték | Leírás | Példa értékek |
|-------------|-----------------------|----------------------------------------------------------------------------------------|------------------------------| |-------------|----------|-----------------------|----------------------------------------------------------------------------------------|------------------------------|
| `icon` | `portainer` | A SimpleIcons ikon neve (kisbetű, kötőjellel). | `github`, `docker`, `nginx` | | `icon` | Igen |`simpleicons` | A SimpleIcons ikon neve (kisbetű, kötőjellel). | `github`, `docker`, `nginx` |
| `label` | `Portainer` | A badge-en megjelenő szöveg. | `MyApp`, `Status` | | `label` | Nem |`Simple Icons` | A badge-en megjelenő szöveg. | `MyApp`, `Status` |
| `bg` | `#f0f0f0` | Háttérszín (hex vagy CSS színnév). | `#fff`, `#222`, `red` | | `bg` | Nem |`#f0f0f0` | Háttérszín (hex vagy CSS színnév). | `#fff`, `#222`, `red` |
| `color` | `#000000` | Szöveg színe (hex vagy CSS színnév). Harmonizál az icon szinével ha nem kérünk külön. | `#333`, `white` | | `color` | Nem |`#000000` | Szöveg színe (hex vagy CSS színnév). Harmonizál az icon szinével ha nem kérünk külön. | `#333`, `white` |
| `size` | `24` | Ikon (és badge) magassága pixelben. | `16`, `32`, `64` | | `size` | Nem |`24` | Ikon (és badge) magassága pixelben. | `16`, `32`, `64` |
| `labelpos` | `right` | Szöveg pozíciója az ikonhoz képest: `right`, `left`, `above`, `below`. | `left`, `above` | | `labelpos` | Nem | `right` | Szöveg pozíciója az ikonhoz képest: `right`, `left`, `above`, `below`. | `left`, `above` |
| `fontweight`| `normal` | Szöveg vastagsága (`normal`, `bold`, `lighter`, szám is lehet pl. `600`). | `bold`, `600` | | `fontweight`| Nem | `normal` | Szöveg vastagsága (`normal`, `bold`, `lighter`, szám is lehet pl. `600`). | `bold`, `600` |
## Példák ## Példák
+85 -37
View File
@@ -6,13 +6,14 @@ const PORT = process.env.PORT || 3000;
app.get('/badge', async (req, res) => { app.get('/badge', async (req, res) => {
const { const {
icon = 'portainer', icon = 'simpleicons',
label = 'Portainer', label = 'Simple Icons',
bg = '#f0f0f0', bgicon = '#cccccc', // ikon háttérszín, alap: világosszürke
bglabel = '#444444', // label háttérszín, alap: sötétszürke
color = '#000000', color = '#000000',
size = 24, size = 24,
labelpos = 'right', // lehet: 'right', 'left', 'above', 'below' labelpos = 'right',
fontweight = 'normal', // új paraméter, alapértelmezett: normal fontweight = 'normal',
} = req.query; } = req.query;
try { try {
@@ -24,6 +25,36 @@ app.get('/badge', async (req, res) => {
} }
const iconSVG = iconResponse.data; const iconSVG = iconResponse.data;
// Ha nincs label paraméter, akkor az ikon SVG <title> mezőjét használjuk
let effectiveLabel = label;
if (!req.query.label || req.query.label === 'Simple Icons') {
const titleMatch = iconSVG.match(/<title>([^<]+)<\/title>/i);
if (titleMatch && titleMatch[1]) {
effectiveLabel = titleMatch[1];
}
}
// Badge méretek
const padding = 10;
const iconSize = parseInt(size);
const fontSize = Math.round(iconSize * 0.6); // Font size az ikon méret 60%-a
const textPadding = Math.round(iconSize * 0.4); // Dinamikus: size 40%-a
const radius = 8;
const approxCharWidth = fontSize * 0.6;
const textWidth = effectiveLabel.length * approxCharWidth;
// Kinyerjük az ikon SVG-ből a width és height attribútumokat (ha vannak)
let iconViewBoxWidth = iconSize;
let iconViewBoxHeight = iconSize;
const widthMatch = iconSVG.match(/width="(\d+\.?\d*)"/);
const heightMatch = iconSVG.match(/height="(\d+\.?\d*)"/);
if (widthMatch) iconViewBoxWidth = parseFloat(widthMatch[1]);
if (heightMatch) iconViewBoxHeight = parseFloat(heightMatch[1]);
// Ikon doboz mérete
const iconBoxWidth = iconViewBoxWidth + 5;
const iconBoxHeight = iconViewBoxHeight + 5;
// Ha a color paraméter nincs megadva, próbáljuk kinyerni az ikon színét // Ha a color paraméter nincs megadva, próbáljuk kinyerni az ikon színét
let effectiveColor = color; let effectiveColor = color;
if (!req.query.color || req.query.color === '#000000') { if (!req.query.color || req.query.color === '#000000') {
@@ -43,45 +74,63 @@ app.get('/badge', async (req, res) => {
} }
} }
// Badge méretek // ÚJ: doboz magasság 5 pixellel nagyobb legyen az ikon méreténél
const padding = 10; const boxHeight = iconSize + 5;
const iconSize = parseInt(size); const labelBoxHeight = boxHeight;
const fontSize = Math.round(iconSize * 0.6); // Font size az ikon méret 60%-a const totalHeight = Math.max(boxHeight, fontSize + padding * 2);
const textPadding = Math.round(iconSize * 0.4); // Dinamikus: size 40%-a
const radius = 8;
const approxCharWidth = fontSize * 0.6;
const textWidth = label.length * approxCharWidth;
let width, height, iconGroup, textElem; let width, height, iconGroup, textElem;
// Szebb, élsimított font shields.io stílusban
const fontFamily = "Verdana,Geneva,DejaVu Sans,sans-serif"; const fontFamily = "Verdana,Geneva,DejaVu Sans,sans-serif";
const fontWeight = fontweight; // paraméterből const fontWeight = fontweight; // paraméterből
if (labelpos === 'above' || labelpos === 'below') { if (labelpos === 'left') {
width = Math.max(iconSize, textWidth) + padding * 2; // Külön dobozok: padding csak a széleken kell, a dobozokon belül nem!
height = padding * 2 + iconSize + textPadding + fontSize; textElem = `<rect x="0" y="0" width="${textWidth}" height="${iconBoxHeight}" rx="${radius}" fill="${bglabel}"/>
if (labelpos === 'above') { <text x="${textWidth / 2}" y="${iconBoxHeight / 2}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="middle">${effectiveLabel}</text>`;
// Szöveg felül, ikon alul iconGroup = `
textElem = `<text x="${width / 2}" y="${padding + fontSize}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="middle">${label}</text>`; <rect x="${textWidth}" y="0" width="${iconBoxWidth + 5}" height="${iconBoxHeight}" rx="${radius}" fill="${bgicon}"/>
iconGroup = `<g transform="translate(${(width - iconSize) / 2}, ${padding + fontSize + textPadding})">${iconSVG}</g>`; <g transform="translate(${textWidth + (5 / 2)}, ${(iconBoxHeight - iconSize) / 2})">${iconSVG}</g>
} else { `;
// Szöveg alul, ikon felül } else if (labelpos === 'above' || labelpos === 'below') {
iconGroup = `<g transform="translate(${(width - iconSize) / 2}, ${padding})">${iconSVG}</g>`; // Felső vagy alsó label: ikon doboz magassága = iconSize + 5, szélessége = szöveg doboz szélessége
textElem = `<text x="${width / 2}" y="${padding + iconSize + textPadding}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="hanging">${label}</text>`; width = Math.max(iconSize + 5, textWidth);
} const labelRectHeight = fontSize + padding;
} else if (labelpos === 'left') { const iconRectY = labelpos === 'above'
width = padding * 2 + iconSize + textPadding + textWidth; ? labelRectHeight
height = Math.max(iconSize + padding * 2, fontSize + padding * 2); : 0;
// Szöveg balra, ikon jobbra (függőleges közép) const labelRectY = labelpos === 'above'
textElem = `<text x="${padding}" y="${height / 2}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" alignment-baseline="middle" dominant-baseline="middle">${label}</text>`; ? 0
iconGroup = `<g transform="translate(${padding + textWidth + textPadding}, ${(height - iconSize) / 2})">${iconSVG}</g>`; : iconSize + 5;
height = iconSize + 5 + textPadding + labelRectHeight;
// Label háttér
const labelRect = `<rect x="0" y="${labelRectY}" width="${width}" height="${labelRectHeight}" rx="${radius}" fill="${bglabel}"/>`;
// Ikon háttér
const iconRect = `<rect x="0" y="${iconRectY}" width="${width}" height="${iconSize + 5}" rx="${radius}" fill="${bgicon}"/>`;
// Szöveg
const textY = labelpos === 'above'
? labelRectY + 5 + labelRectHeight / 2
: labelRectY + 5 + labelRectHeight / 2;
textElem = `
${labelRect}
<text x="${width / 2}" y="${textY}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="middle">${effectiveLabel}</text>
`;
// Ikon
iconGroup = `
${iconRect}
<g transform="translate(${(width - iconSize) / 2 + 2.5}, ${iconRectY + (iconSize + 5 - iconSize) / 2})">${iconSVG}</g>
`;
} else { } else {
width = padding * 2 + iconSize + textPadding + textWidth;
height = Math.max(iconSize + padding * 2, fontSize + padding * 2);
// Alapértelmezett: ikon balra, szöveg jobbra (függőleges közép) // Alapértelmezett: ikon balra, szöveg jobbra (függőleges közép)
iconGroup = `<g transform="translate(${padding}, ${(height - iconSize) / 2})">${iconSVG}</g>`; iconGroup = `
textElem = `<text x="${padding + iconSize + textPadding + textWidth / 2}" y="${height / 2}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="middle">${label}</text>`; <rect x="0" y="0" width="${iconBoxWidth}" height="${iconBoxHeight}" rx="${radius}" fill="${bgicon}"/>
<g transform="translate(${(iconBoxWidth - iconViewBoxWidth) / 2}, ${(iconBoxHeight - iconViewBoxHeight) / 2})">${iconSVG}</g>
`;
textElem = `<rect x="${iconBoxWidth}" y="0" width="${textWidth}" height="${iconBoxHeight}" rx="${radius}" fill="${bglabel}"/>
<text x="${iconBoxWidth + textWidth / 2}" y="${iconBoxHeight / 2}" font-size="${fontSize}" font-family="${fontFamily}" font-weight="${fontWeight}" fill="${effectiveColor}" text-anchor="middle" dominant-baseline="middle">${effectiveLabel}</text>`;
} }
// SVG badge string összefűzéssel, szöveg árnyékkal // SVG badge string összefűzéssel, szöveg árnyékkal
@@ -92,7 +141,6 @@ app.get('/badge', async (req, res) => {
<feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="#000" flood-opacity="0.25"/> <feDropShadow dx="0" dy="1" stdDeviation="1" flood-color="#000" flood-opacity="0.25"/>
</filter> </filter>
</defs> </defs>
<rect x="0" y="0" width="${width}" height="${height}" rx="${radius}" fill="${bg}"/>
${iconGroup} ${iconGroup}
${textElem.replace('<text ', '<text filter="url(#shadow)" ')} ${textElem.replace('<text ', '<text filter="url(#shadow)" ')}
</svg> </svg>