diff --git a/public/assets/images/blog-default-cover.png b/public/assets/images/blog-default-cover.png index 7f5dcb1..027e8c1 100644 Binary files a/public/assets/images/blog-default-cover.png and b/public/assets/images/blog-default-cover.png differ diff --git a/scripts/make-blog-cover.mjs b/scripts/make-blog-cover.mjs index 2db77a9..535d2ba 100644 --- a/scripts/make-blog-cover.mjs +++ b/scripts/make-blog-cover.mjs @@ -25,31 +25,77 @@ const mark = readFileSync(join(ROOT, 'public/nobat724.svg'), 'utf8') .replace(/<\?xml[^>]*\?>/, '') .replace(/width="\d+"\s+height="\d+"/, 'width="200" height="200"'); -const fontPath = join(ROOT, 'public/fonts/vazir/Vazirmatn-RD-FD-Bold.ttf'); -const fontData = readFileSync(fontPath).toString('base64'); +/** + * چیدمان RTL: لوگو سمت راست، «اسکلتون» یک مقاله سمت چپ — کارت سفید با جای + * تصویر شاخص، یک نوار عنوان و چند خط پاراگراف. همان زبان بصریِ حالت بارگذاری، + * پس «مقالهٔ بدون کاور» به‌جای عکس بی‌ربط، قالبِ خالی مقاله را نشان می‌دهد. + * + * خط‌ها راست‌چین‌اند (RTL) و عرضشان نامنظم است تا شبیه متن واقعی باشد؛ خط آخر + * کوتاه است، همان‌طور که آخرین سطر یک پاراگراف کوتاه می‌افتد. + */ +const CARD = { x: 132, y: 88, w: 628, h: 410, pad: 40 }; +const INNER_RIGHT = CARD.x + CARD.w - CARD.pad; +const INNER_W = CARD.w - CARD.pad * 2; + +// عرض هر سطر پاراگراف نسبت به عرض داخلی کارت +const PARAGRAPH = [1, 0.94, 0.99, 0.88, 0.52]; + +const lines = PARAGRAPH.map((ratio, i) => { + const w = Math.round(INNER_W * ratio); + return { x: INNER_RIGHT - w, y: 344 + i * 26, w, h: 14 }; +}); const svg = ` - + + + + + + + + + + + + - - - ${mark} - نوبت ۷۲۴ - مقالات و اخبار پزشکی + + + + + + + + + + + + + + + + + + + ${lines + .map( + (b) => + `` + ) + .join('\n ')} + + + ${mark} `; // density بالا برای متن تیز، سپس resize به ابعاد دقیق OG.