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 0000000..4a7e8c4
Binary files /dev/null and b/public/apple-touch-icon.png differ
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 0000000..08f3692
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..08f3692
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 0000000..6f66aa4
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,13 @@
+
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 @@