POLS / aries /src /publish.js
Ethscriptions's picture
aries: 配乐音效、播放器、铭牌导出、MP4 导出、四平台文案与封面、首页入口
f84718b
Raw History Blame Contribute Delete
6.53 kB
// ♈ 四平台发布文案 + 封面绘制
import { drawBadge } from './badge.js';
import { say, bloom, embers, star, hash, rgba, SERIF, SANS, DISPLAY, GOLD, PI2, ariesGlyph, gold } from './kit.js';
import { TIMELINE } from './timeline.js';
const mmss = t => `${String(Math.floor(t / 60)).padStart(2, '0')}:${String(Math.floor(t % 60)).padStart(2, '0')}`;
const chapters = () => TIMELINE.acts.map(a => `${mmss(a.t0)} ${a.title}`).join('\n');
export const PLATFORMS = [
{
id: 'xhs', name: '小红书', limits: { title: 20, tags: 10 },
title: '白羊座为什么排第一?3分钟看懂',
desc: `白羊座的朋友请进🔥\n\n为什么白羊座是黄道第一宫?\n夜空里的“羊角”在哪里?\n金羊毛的神话讲了什么?\n♈ 这个符号又藏着什么秘密?\n\n3 分钟动画一次讲清~\n最后还有一枚只属于白羊座的「先锋荣耀铭牌」🏅\n可以写上你的名字,保存成壁纸和头像!\n\n星座是一份浪漫又有趣的文化,愿每个白羊都被星光照亮✨`,
tags: ['白羊座', '星座', '十二星座', '星座文化', '白羊座的你', '金羊毛', '星空', '动画科普', '春分', '星座壁纸'],
covers: ['4x3', '3x4'],
},
{
id: 'douyin', name: '抖音', limits: { title: 30, tags: 5 },
title: '白羊座看过来!这枚先锋铭牌,只颁给春天第一个出发的你',
desc: '黄道第一宫、金羊毛神话、♈ 的秘密……3 分钟看懂白羊座,结尾领取你的白羊座荣耀铭牌🔥 评论区报上你的生日!',
tags: ['白羊座', '星座', '十二星座', '星座文化', '金羊毛'],
covers: ['4x3', '3x4'],
},
{
id: 'bilibili', name: 'B站', limits: { title: 80, tags: 10 },
title: '【星座动画】白羊座为什么是黄道第一宫?金羊毛神话、哈马尔与♈的秘密|看完领取你的白羊座荣耀铭牌',
desc: () => `一支关于白羊座(Aries)的原创动画。\n\n春分点为什么叫“白羊座第一点”?夜空中如何找到白羊座?哈马尔、娄宿二的名字从何而来?金羊毛的神话怎样让一只公羊升上星空?♈ 符号又是羊角还是嫩芽?\n\n星座不是科学,但它是一份浪漫、有趣、值得骄傲的文化。献给每一位白羊座——愿你的每一次出发,都被星光照亮。\n\n章节:\n${chapters()}\n\n🏅 视频页面可输入名字,生成专属「白羊座 · 先锋荣耀铭牌」壁纸 / 头像。\n画面、旁白、配乐均为原创网页实时渲染。`,
tags: ['白羊座', '星座', '十二星座', '星座文化', '天文', '希腊神话', '金羊毛', '动画', '科普', '星空'],
covers: ['4x3', '16x9'],
},
{
id: 'wechat', name: '视频号', limits: { title: 16, tags: Infinity },
title: '白羊座:春天从这里出发',
desc: '黄道第一宫的浪漫故事:春分、星空、金羊毛与 ♈ 的秘密。献给每一位白羊座,愿你的每一次出发,都被星光照亮。',
tags: ['白羊座', '星座', '十二星座', '星座文化', '金羊毛', '星空', '春分', '希腊神话', '白羊座的你', '动画'],
covers: ['3x4', '4x3'],
},
];
export const COVER_SIZE = { '4x3': [1440, 1080], '3x4': [1080, 1440], '16x9': [1920, 1080] };
const HOOK = { xhs: '为什么排第一?', douyin: '你的先锋铭牌到了', bilibili: '黄道第一宫的秘密', wechat: '春天从这里出发' };
export const countChars = s => [...s].length;
/** 封面:背景(paintBg)+ 铭牌 + 大标题 */
export function drawCover(ctx, W, H, pid, paintBg) {
paintBg(ctx, W, H);
const S = Math.min(W, H) / 1080, portrait = H > W, wide = W / H > 1.6;
embers(ctx, 3.3, W, H, { n: 60, seed: 5, alpha: .9 });
// 版式
const size = portrait ? Math.min(W * .95, (H - 600 * S) / .97) : H * .78;
const bx = portrait ? W / 2 : W * (wide ? .68 : .7), by = portrait ? 440 * S + .47 * size : H * .53;
ctx.save(); ctx.globalCompositeOperation = 'lighter';
for (let i = 0; i < 24; i++) { const a = i / 24 * PI2, L = Math.max(W, H); ctx.fillStyle = rgba([255, 190, 110], .05); ctx.beginPath(); ctx.moveTo(bx, by); ctx.lineTo(bx + Math.cos(a - .05) * L, by + Math.sin(a - .05) * L); ctx.lineTo(bx + Math.cos(a + .05) * L, by + Math.sin(a + .05) * L); ctx.fill(); }
ctx.restore();
bloom(ctx, bx, by, 600 * S, [255, 150, 70], .6);
drawBadge(ctx, bx, by, size, { t: 2.2, forge: 1, engrave: 1, ribbon: 1, name: 1 });
for (let i = 0; i < 26; i++) star(ctx, W * hash(i + 3), H * hash(i + 31), (1 + hash(i) * 3) * S, [255, 230, 180], .7, hash(i + 9) > .7 ? 1 : 0);
const hook = HOOK[pid] || HOOK.xhs;
const banner = (x, y, sz) => {
ctx.save(); ctx.font = `900 ${sz}px ${SERIF}`; const hw = ctx.measureText(hook).width + sz * 1.3; ctx.restore();
ctx.save(); const g = ctx.createLinearGradient(0, y - sz * .8, 0, y + sz * .8); g.addColorStop(0, '#e2392d'); g.addColorStop(1, '#8e1712'); ctx.fillStyle = g;
ctx.shadowColor = 'rgba(0,0,0,.5)'; ctx.shadowBlur = 20 * S; ctx.fillRect(x - hw / 2, y - sz * .8, hw, sz * 1.6); ctx.shadowColor = 'transparent';
ctx.strokeStyle = gold(ctx, x - hw / 2, y, x + hw / 2, y); ctx.lineWidth = 3 * S; ctx.strokeRect(x - hw / 2 + 7 * S, y - sz * .8 + 7 * S, hw - 14 * S, sz * 1.6 - 14 * S); ctx.restore();
say(ctx, hook, x, y + 2 * S, { size: sz, fill: '#fff4dc', weight: 900, shadow: 'rgba(60,0,0,.8)', blur: 8 * S });
};
if (portrait) {
ariesGlyph(ctx, W / 2 - 340 * S, 175 * S, .42 * S, 1, { width: 14 });
ariesGlyph(ctx, W / 2 + 340 * S, 175 * S, .42 * S, 1, { width: 14 });
say(ctx, '白羊座', W / 2, 180 * S, { size: 160 * S, metal: true, weight: 900, track: 14 * S, shadow: 'rgba(255,110,30,.85)', blur: 40 * S });
say(ctx, 'ARIES · 黄道第一宫 · 3.21 — 4.19', W / 2, 300 * S, { size: 34 * S, fill: '#ffe2b0', font: SERIF, weight: 700, track: 3 * S });
banner(W / 2, H - 80 * S, 62 * S);
} else {
const tx = W * (wide ? .27 : .24), ts = wide ? 1 : .9;
ariesGlyph(ctx, tx, H * .2, .6 * S * ts, 1, { width: 14 });
say(ctx, '白羊座', tx, H * .4, { size: 150 * S * ts, metal: true, weight: 900, track: 12 * S, shadow: 'rgba(255,110,30,.85)', blur: 40 * S });
say(ctx, 'ARIES', tx, H * .4 + 105 * S * ts, { size: 42 * S, fill: '#ffd98f', font: DISPLAY, weight: 700, track: 16 * S });
banner(tx, H * .66, 54 * S * ts);
say(ctx, '黄道第一宫 · 3.21 — 4.19', tx, H * .66 + 105 * S, { size: 32 * S * ts, fill: '#ffe2b0', font: SERIF, weight: 700, track: 4 * S });
}
}