This commit is contained in:
amirhosein.ashourloo
2026-08-19 17:54:11 +03:30
parent b065fac757
commit 149b77f734
80 changed files with 3015 additions and 92 deletions
+85
View File
@@ -0,0 +1,85 @@
// Generates flat, neutral placeholder SVG images so every image slot on the
// homepage has a real file on disk that can be swapped later without any
// code changes. Run with: node scripts/gen-placeholders.mjs
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const PUBLIC = join(__dirname, "..", "public", "images");
// Two flat, muted tones so placeholders alternate subtly instead of being
// one flat wall of gray.
const TONES = ["#EBEDE9", "#E4E7E2"];
function icon(cx, cy, s, stroke) {
// Simple flat "image" glyph: rounded frame + mountain + sun dot.
return `
<g transform="translate(${cx - s / 2} ${cy - s / 2})" fill="none" stroke="${stroke}" stroke-width="${Math.max(
2,
s * 0.045
)}" stroke-linejoin="round" stroke-linecap="round">
<rect x="0" y="0" width="${s}" height="${s * 0.72}" rx="${s * 0.06}" />
<circle cx="${s * 0.24}" cy="${s * 0.24}" r="${s * 0.07}" />
<path d="M0 ${s * 0.58} L${s * 0.32} ${s * 0.32} L${s * 0.56} ${s * 0.5} L${s * 0.78} ${s * 0.3} L${s} ${
s * 0.5
}" />
</g>`;
}
function svgPlaceholder({ w, h, label, tone }) {
const s = Math.min(w, h) * 0.22;
const cx = w / 2;
const cy = h / 2 - s * 0.12;
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${w} ${h}" width="${w}" height="${h}">
<rect width="${w}" height="${h}" fill="${tone}" />
${icon(cx, cy, s, "#B9BEB4")}
<text x="${cx}" y="${cy + s * 0.62 + s * 0.34}" text-anchor="middle" font-family="Arial, sans-serif" font-size="${Math.max(
11,
s * 0.16
)}" fill="#9AA096" letter-spacing="1">${label} · ${w}×${h}</text>
</svg>`;
}
let toneIndex = 0;
function nextTone() {
const t = TONES[toneIndex % TONES.length];
toneIndex += 1;
return t;
}
function write(relPath, w, h, label) {
const full = join(PUBLIC, relPath);
mkdirSync(dirname(full), { recursive: true });
writeFileSync(full, svgPlaceholder({ w, h, label, tone: nextTone() }), "utf8");
console.log("wrote", relPath);
}
// Hero slider — full width slides
for (let i = 1; i <= 3; i++) write(`hero/slide-${i}.svg`, 1600, 560, "HERO SLIDE");
// Special sale carousel — first card is a banner image, rest are product shots
write("special-sale/banner.svg", 480, 620, "SALE BANNER");
for (let i = 1; i <= 8; i++) write(`special-sale/product-${i}.svg`, 480, 620, "SALE ITEM");
// Categories
const categories = ["girls", "boys", "baby", "party", "sets", "outerwear"];
for (const key of categories) write(`categories/${key}.svg`, 520, 600, "CATEGORY");
// Two-banner section
write("banners/banner-1.svg", 770, 360, "BANNER");
write("banners/banner-2.svg", 770, 360, "BANNER");
// Single full-width banner
write("banners/full-banner.svg", 1600, 420, "FULL BANNER");
// Top selling products carousel
for (let i = 1; i <= 12; i++) write(`products/product-${i}.svg`, 480, 620, "PRODUCT");
// About us
write("about/about.svg", 720, 640, "ABOUT US");
// Blog carousel
for (let i = 1; i <= 4; i++) write(`blog/post-${i}.svg`, 520, 380, "BLOG");
console.log("Done. Placeholder images generated in public/images/");