From fbe239c1fec372302a3e7adf86d8045e3887900c Mon Sep 17 00:00:00 2001 From: sHa Date: Mon, 12 May 2025 16:54:41 +0300 Subject: [PATCH] Added favicon --- .gitignore | 3 ++ Makefile | 11 +++++- package.json | 4 ++- public/apple-touch-icon.png | Bin 0 -> 3132 bytes public/data/logos.json | 53 ++++++++++++++++++++++++++- public/favicon.ico | Bin 0 -> 632 bytes public/favicon.png | Bin 0 -> 632 bytes public/favicon.svg | 13 +++++++ public/favicon_big.svg | 21 +++++++++++ public/index.html | 6 ++++ public/logos/honda.svg | 18 ++++++++++ public/logos/toyota.svg | 4 +++ public/logos/toyota_logo.svg | 4 +++ scripts/generateFavicons.js | 68 +++++++++++++++++++++++++++++++++++ scripts/scanLogos.js | 14 +++++--- src/components/Header.svelte | 24 ++++++++++++- 16 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 public/apple-touch-icon.png create mode 100644 public/favicon.ico create mode 100644 public/favicon.png create mode 100644 public/favicon.svg create mode 100644 public/favicon_big.svg create mode 100644 public/logos/honda.svg create mode 100644 public/logos/toyota.svg create mode 100644 public/logos/toyota_logo.svg create mode 100644 scripts/generateFavicons.js diff --git a/.gitignore b/.gitignore index 18990c4..0e2c926 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ Temporary Items .env.development .env.test .env.production + +# Make favicon generation script executable +chmod +x ./scripts/generateFavicons.js diff --git a/Makefile b/Makefile index 9a337fb..ed92203 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ CONTAINER_NAME = logo-gallery DEV_PORT = 5006 # Main targets -.PHONY: all build start stop restart logs clean scan-logos dev rebuild +.PHONY: all build start stop restart logs clean scan-logos dev rebuild favicon deps-favicon build-with-favicons all: build start @@ -60,3 +60,12 @@ clean: rebuild: $(DOCKER_COMPOSE) -f compose.dev.yml down -v $(DOCKER_COMPOSE) -f compose.dev.yml build --no-cache + +# Generate favicons +favicon: + @echo "Generating favicons..." + $(DOCKER_COMPOSE) -f compose.dev.yml run --rm slogos-dev npm run generate-favicons + @echo "Favicons have been generated" + +# Build with favicons +build-with-favicons: favicon build diff --git a/package.json b/package.json index 659bcf1..9addf3e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "build": "rollup -c", "dev": "rollup -c -w", "start": "sirv public --host 0.0.0.0 --dev --single", - "scan-logos": "node scripts/scanLogos.js" + "scan-logos": "node scripts/scanLogos.js", + "generate-favicons": "node scripts/generateFavicons.js" }, "devDependencies": { "@rollup/plugin-commonjs": "^17.0.0", @@ -20,6 +21,7 @@ }, "dependencies": { "@resvg/resvg-js": "^2.0.1", + "jimp": "^0.22.10", "sirv-cli": "^1.0.0" } } diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4a7e8c40976ea39e4709968df92fb0e48fcf903f GIT binary patch literal 3132 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 literal 0 HcmV?d00001 diff --git a/public/data/logos.json b/public/data/logos.json index af263cc..b46a403 100644 --- a/public/data/logos.json +++ b/public/data/logos.json @@ -485,6 +485,17 @@ ], "brand": "Home Assistant" }, + { + "name": "Honda", + "path": "logos/honda.svg", + "format": "SVG", + "disable": false, + "tags": [ + "automobile", + "transport" + ], + "brand": "Honda" + }, { "name": "IBKR", "path": "logos/ibkr.svg", @@ -1258,6 +1269,46 @@ ], "brand": "Threads" }, + { + "name": "Toyota", + "path": "logos/toyota.svg", + "format": "SVG", + "disable": false, + "tags": [ + "automobile", + "transport" + ], + "brand": "Toyota", + "colors": [ + { + "label": "Red", + "value": "#EB0A1E" + } + ], + "colorConfig": { + "target": "path" + } + }, + { + "name": "Toyota Logo", + "path": "logos/toyota_logo.svg", + "format": "SVG", + "disable": false, + "tags": [ + "automobile", + "transport" + ], + "brand": "Toyota", + "colors": [ + { + "label": "Red", + "value": "#EB0A1E" + } + ], + "colorConfig": { + "target": "path" + } + }, { "name": "Ubuntu", "path": "logos/ubuntu.svg", @@ -1365,4 +1416,4 @@ "tags": [], "brand": "Youtube" } -] +] \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..08f369246ded1202a817e6b91bd76316479a9d99 GIT binary patch literal 632 zcmV-;0*C#HP)C`PzOb)%3(>M5RQVNhwt9+wJ%Qh?%w#mFQljM?qL_1Sp`mna6f$bTYC8R$t@|J zp{v@35Z3Shx%sp2{|F}O2%Csz<=BtdMW$NBmXvy4OKBTj^L3@P?X^kjVGB{U47(AT zdYMwDUZ#|(mqiVW8WuGyYFI>}UZIrKOG<@$MZ}541{f-xVr;%KPL+ljSnMREpWX|K zqKC|^0>g0U_lau{SASf>vT9d%Uwk_9zwe&6&_gsUmxZCGg_j@qZ%MY1nUw^mD~|`~ zranJ^=Pl9$bX2<}9DK9({2xfjBP%^cb zc2<{ghPJuV{fMr`+E`ZVsMk?iM%!ZDs9{mVqJ~8ciy9VjVX-l;lrGh~RJy|0Vi%cU zU9yeLtR#4}@^~=vMmQju>Zo=}I4~8yeKATqtLxZ6Fe?|rp{9jT_Wln4P9{BMW)*_r zlP_*eTzhu&gC)|kO5y7Et6xU0^^fkg5U zGqhD3WBvB4U(fqT_gaak=$r32V$))M^prNxHeVYXrV>5$Ew&jE)r(3&y`U7;i&4X( zhD8mF8WxeOmn-G!E4sl_=3&NqPmevr*C{)V{`~Lx(D6J(J Sl}ZBu0000C`PzOb)%3(>M5RQVNhwt9+wJ%Qh?%w#mFQljM?qL_1Sp`mna6f$bTYC8R$t@|J zp{v@35Z3Shx%sp2{|F}O2%Csz<=BtdMW$NBmXvy4OKBTj^L3@P?X^kjVGB{U47(AT zdYMwDUZ#|(mqiVW8WuGyYFI>}UZIrKOG<@$MZ}541{f-xVr;%KPL+ljSnMREpWX|K zqKC|^0>g0U_lau{SASf>vT9d%Uwk_9zwe&6&_gsUmxZCGg_j@qZ%MY1nUw^mD~|`~ zranJ^=Pl9$bX2<}9DK9({2xfjBP%^cb zc2<{ghPJuV{fMr`+E`ZVsMk?iM%!ZDs9{mVqJ~8ciy9VjVX-l;lrGh~RJy|0Vi%cU zU9yeLtR#4}@^~=vMmQju>Zo=}I4~8yeKATqtLxZ6Fe?|rp{9jT_Wln4P9{BMW)*_r zlP_*eTzhu&gC)|kO5y7Et6xU0^^fkg5U zGqhD3WBvB4U(fqT_gaak=$r32V$))M^prNxHeVYXrV>5$Ew&jE)r(3&y`U7;i&4X( zhD8mF8WxeOmn-G!E4sl_=3&NqPmevr*C{)V{`~Lx(D6J(J Sl}ZBu0000 + + + + + + + + + + + + diff --git a/public/favicon_big.svg b/public/favicon_big.svg new file mode 100644 index 0000000..1603c3c --- /dev/null +++ b/public/favicon_big.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/public/index.html b/public/index.html index d97b13d..6a098e9 100644 --- a/public/index.html +++ b/public/index.html @@ -6,6 +6,12 @@ Logo Gallery + + + + + +
diff --git a/public/logos/honda.svg b/public/logos/honda.svg new file mode 100644 index 0000000..a3dce23 --- /dev/null +++ b/public/logos/honda.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/public/logos/toyota.svg b/public/logos/toyota.svg new file mode 100644 index 0000000..7e3631e --- /dev/null +++ b/public/logos/toyota.svg @@ -0,0 +1,4 @@ + + + diff --git a/public/logos/toyota_logo.svg b/public/logos/toyota_logo.svg new file mode 100644 index 0000000..170488a --- /dev/null +++ b/public/logos/toyota_logo.svg @@ -0,0 +1,4 @@ + + + diff --git a/scripts/generateFavicons.js b/scripts/generateFavicons.js new file mode 100644 index 0000000..a4ea807 --- /dev/null +++ b/scripts/generateFavicons.js @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); +const { Resvg } = require('@resvg/resvg-js'); +const jimp = require('jimp'); + +// Paths +const srcSvgPath = path.join(__dirname, '../public/favicon.svg'); +const pngOutputPath = path.join(__dirname, '../public/apple-touch-icon.png'); +const icoOutputPath = path.join(__dirname, '../public/favicon.ico'); +const faviconPngPath = path.join(__dirname, '../public/favicon.png'); + +// Ensure the favicon.svg file exists +if (!fs.existsSync(srcSvgPath)) { + console.error('Error: favicon.svg not found in public directory.'); + process.exit(1); +} + +console.log('Generating favicons from SVG...'); + +async function generateFavicons() { + try { + // Read the SVG file + const svgData = fs.readFileSync(srcSvgPath, 'utf8'); + + // Render SVG to PNG using Resvg - maintain transparency + const opts = { + // No background specified to maintain transparency + fitTo: { + mode: 'width', + value: 1024 + } + }; + const resvg = new Resvg(svgData, opts); + const pngData = resvg.render(); + const pngBuffer = pngData.asPng(); + + // Save a temporary high-resolution PNG + const tempPngPath = path.join(__dirname, '../public/temp-favicon.png'); + fs.writeFileSync(tempPngPath, pngBuffer); + + // Generate apple-touch-icon.png (180x180) using jimp + const appleIconImg = await jimp.read(tempPngPath); + await appleIconImg.resize(180, 180).writeAsync(pngOutputPath); + console.log(`Created ${pngOutputPath}`); + + // Create favicon.png (32x32) for browsers that support PNG favicons + const faviconPng = await jimp.read(tempPngPath); + await faviconPng.resize(32, 32).writeAsync(faviconPngPath); + console.log(`Created ${faviconPngPath}`); + + // For favicon.ico, we'll just use the 32x32 PNG since we don't have ico-encoder + // Most modern browsers will use the PNG or SVG anyway + fs.copyFileSync(faviconPngPath, icoOutputPath); + console.log(`Created ${icoOutputPath} (Note: This is actually a PNG file renamed to .ico)`); + + // Clean up temporary file + fs.unlinkSync(tempPngPath); + + console.log('Favicon generation completed successfully!'); + } catch (error) { + console.error('Error generating favicons:', error); + process.exit(1); + } +} + +generateFavicons(); diff --git a/scripts/scanLogos.js b/scripts/scanLogos.js index 35b9fa2..70f0f53 100644 --- a/scripts/scanLogos.js +++ b/scripts/scanLogos.js @@ -51,17 +51,23 @@ function cleanDir(dir) { } } -// Convert SVG to PNG +// Convert SVG to PNG with transparency function svgToPng(svgBuffer, width, height) { - const resvg = new Resvg(svgBuffer, { fitTo: { mode: 'width', value: width || 256 } }); + // No background specified to maintain transparency + const resvg = new Resvg(svgBuffer, { + fitTo: { mode: 'width', value: width || 256 } + }); const pngData = resvg.render().asPng(); return pngData; } // Convert SVG to JPG function svgToJpg(svgBuffer, width, height) { - const resvg = new Resvg(svgBuffer, { fitTo: { mode: 'width', value: width || 256 } }); - // Convert PNG buffer to JPEG using a pure JS lib, or just save as PNG (JPEG is optional) + // For JPGs we need a white background since JPG doesn't support transparency + const resvg = new Resvg(svgBuffer, { + background: 'white', + fitTo: { mode: 'width', value: width || 256 } + }); const pngData = resvg.render().asPng(); return pngData; } diff --git a/src/components/Header.svelte b/src/components/Header.svelte index 68e94e5..48b3a7d 100644 --- a/src/components/Header.svelte +++ b/src/components/Header.svelte @@ -39,7 +39,12 @@
-

Logo Gallery

+
+
+ Logo Gallery icon +
+

Logo Gallery

+
{#if displayLogos && logos && displayLogos.length === logos.length} {logos.length} images in gallery @@ -290,6 +295,23 @@