POLS / taurus /js /release.js
Ethscriptions's picture
taurus: 配乐混音、MP4 导出、页面、发布包与 8 张封面
9b7ae8a verified
Raw History Blame Contribute Delete
6.87 kB
// ♉ 金牛座 —— 四平台发布文案与封面(全新编写)
import { clamp, h1, col, C, FONT, gilt, halo, text, divider, flower, petals, bullSide, taurusSign, sparkle, dust, ornamentFrame } from './canvas-kit.js';
import { drawCard } from './card.js';
export const charCount = s => [...s].length;
export const COVER_PX = { '4:3': [1440, 1080], '3:4': [1080, 1440], '16:9': [1920, 1080] };
const TAGS_ALL = ['金牛座', '星座', '十二星座', '星座文化', '金牛座女生', '金牛座男生', '天文', '昴星团', '星空', '治愈系', '浪漫', '古代天文', '希腊神话', '动画'];
export const PLATFORMS = [
{ id: 'xhs', name: '小红书', titleMax: 20, tagMax: 10, covers: ['3:4', '4:3'],
title: '金牛座的鎏金珍藏卡,请收下✨',
desc: '4 月 20 日—5 月 20 日出生的你,这条视频是写给你的。\n\n🌾 五千年前,春分的太阳落在金牛座,那是播种的季节\n⭐ 公牛之眼毕宿五、七姐妹昴星团,冬夜抬头就能找到\n🏮 1054 年北宋天文官记下“天关客星”,白昼可见 23 天——它就是今天的蟹状星云\n💐 欧罗巴与白牛的神话,让“欧洲”有了名字\n\n结尾有一张属于你的「金牛座 · 鎏金珍藏卡」,可以写上名字和生日,保存成壁纸或头像。\n慢慢来,也能抵达所有的美好。',
tags: ['金牛座', '星座', '十二星座', '星座文化', '金牛座女生', '星空', '昴星团', '治愈系', '浪漫', '天文'] },
{ id: 'douyin', name: '抖音', titleMax: 30, tagMax: 5, covers: ['3:4', '4:3'],
title: '金牛座:最古老的星座,藏着中国人的千年骄傲',
desc: '4.20—5.20 的金牛座看过来🐂 一万七千年前的壁画、北宋的天关客星、欧罗巴的白牛……最后送你一张鎏金珍藏卡,评论区晒出你的名字!',
tags: ['金牛座', '星座', '十二星座', '星座文化', '星空'] },
{ id: 'bili', name: 'B站', titleMax: 80, tagMax: 10, covers: ['16:9', '4:3'],
title: '【星座文化】金牛座全解:从一万七千年前的洞穴壁画、北宋“天关客星”到欧罗巴神话|附鎏金珍藏卡',
desc: '一支关于金牛座的原创动画短片(约 4 分 10 秒)。\n\n00:00 序章 · 繁花里的公牛\n00:27 最古老的星座\n00:53 找到它:猎户腰带 → 毕宿五 → 毕星团 → 昴星团\n01:23 毕宿五与昴星团\n01:53 天关客星:1054 年的超新星与蟹状星云\n02:23 欧罗巴与白牛\n02:52 ♉ 的含义\n03:08 土象 · 金星\n03:32 鎏金珍藏卡\n03:52 尾声 · 慢慢来\n\n星座是一种有趣、浪漫的文化。网页版可以输入名字与生日,生成并下载属于自己的珍藏卡。',
tags: ['金牛座', '星座', '十二星座', '星座文化', '天文', '古代天文', '希腊神话', '昴星团', '超新星', '动画短片'] },
{ id: 'channels', name: '视频号', titleMax: 16, tagMax: 99, covers: ['3:4', '4:3'],
title: '金牛座,慢慢来也很美好',
desc: '写给每一位金牛座:稳稳的你,值得一张鎏金珍藏卡。转给你身边那个 4 月 20 日—5 月 20 日出生的朋友吧。',
tags: ['金牛座', '星座', '十二星座', '星座文化', '星空', '天文', '治愈', '浪漫', '金牛座女生', '金牛座男生'] },
];
// 每个平台封面主副标题(不同平台给出不同的钩子)
const HOOK = {
xhs: ['金牛座', '这张鎏金珍藏卡\n属于你'], douyin: ['金牛座', '最古老的星座'], bili: ['金牛座', '从壁画到超新星'], channels: ['金牛座', '慢慢来 也很美好'],
};
function paintBg(g, W, H, warm = 0) {
const gr = g.createLinearGradient(0, 0, W * .3, H); gr.addColorStop(0, warm ? '#3a1a2c' : '#0d2a24'); gr.addColorStop(.55, warm ? '#2a1424' : '#1a1c26'); gr.addColorStop(1, '#0b0a0e');
g.fillStyle = gr; g.fillRect(0, 0, W, H);
const S = Math.min(W, H) / 1080;
for (let i = 0; i < 14; i++) halo(g, W * h1(i * 3.1), H * h1(i * 5.7), (120 + h1(i) * 260) * S, i % 2 ? [220, 120, 150] : [60, 150, 120], .16);
for (let i = 0; i < 180; i++) { g.fillStyle = col([255, 245, 230], .2 + .6 * h1(i * 9)); g.beginPath(); g.arc(W * h1(i * 1.3), H * h1(i * 2.9) * .8, (.6 + 1.8 * Math.pow(h1(i * 4), 3)) * S, 0, Math.PI * 2); g.fill(); }
const v = g.createRadialGradient(W / 2, H / 2, Math.min(W, H) * .3, W / 2, H / 2, Math.max(W, H) * .75); v.addColorStop(0, 'rgba(0,0,0,0)'); v.addColorStop(1, 'rgba(0,0,0,.55)'); g.fillStyle = v; g.fillRect(0, 0, W, H);
}
export { paintBg };
export function drawCover(g, W, H, pid, name = '') {
const S = Math.min(W, H) / 1080, P = H > W, [h1t, h2t] = HOOK[pid] || HOOK.xhs;
paintBg(g, W, H, pid === 'xhs' || pid === 'channels');
petals(g, 3.3, W, H, { n: 34, alpha: .8, seed: 5 });
// 四角花
[[0, 0], [W, 0], [0, H], [W, H]].forEach(([x, y], i) => { for (let k = 0; k < 4; k++) flower(g, x + (x ? -1 : 1) * (40 + k * 70 + h1(i * 7 + k) * 30) * S, y + (y ? -1 : 1) * (40 + h1(i + k * 3) * 120) * S, (34 + h1(k + i) * 30) * S, 1, { rot: i + k, inner: k % 2 ? [220, 100, 130] : [240, 170, 120], outer: [255, 236, 230] }); });
ornamentFrame(g, 26 * S, 26 * S, W - 52 * S, H - 52 * S, { S: S * .9, alpha: .9, metal: 'gold' });
// 卡片
const wide = W / H > 1.5, ch = P ? H * .5 : H * (wide ? .8 : .7), cx = P ? W / 2 : W * (wide ? .7 : .71), cy = P ? H * .64 : H * .52;
halo(g, cx, cy, ch * .9, [255, 200, 150], .7);
drawCard(g, cx, cy, ch, { t: 1.6, flip: 1, fields: 1, shine: .58, holo: .6, stamp: 1, holder: name, tilt: P ? 0 : -.05 });
for (let i = 0; i < 16; i++) sparkle(g, cx + (h1(i * 3) - .5) * ch * 1.1, cy + (h1(i * 7) - .5) * ch * 1.1, (2 + h1(i) * 4) * S, C.ivory, .9, .8);
// 标题区
const tx = P ? W / 2 : W * (wide ? .3 : .28), ty = P ? H * .19 : H * .33, big = (P ? 180 : wide ? 190 : 140) * S;
taurusSign(g, tx, ty - big * .95, (P ? .55 : .5) * S, 1, { width: 12 });
text(g, h1t, tx, ty, { size: big, gilt: 'gold', weight: 900, spacing: 10 * S, glow: 'rgba(255,170,120,.55)', blur: 30 * S });
const lines = h2t.split('\n'), sz = (P ? 72 : wide ? 68 : 58) * S;
if (P) text(g, lines.join(''), tx, ty + big * .78, { size: sz * (lines.join('').length > 8 ? .82 : 1), gilt: 'rose', weight: 900, spacing: 4 * S, outline: 'rgba(20,8,12,.7)', outlineW: 8 * S });
else lines.forEach((l, i) => text(g, l, tx, ty + big * .8 + i * sz * 1.25, { size: sz, gilt: 'rose', weight: 900, spacing: 4 * S, outline: 'rgba(20,8,12,.7)', outlineW: 8 * S }));
const by = P ? ty + big * .78 + 74 * S : ty + big * .8 + lines.length * sz * 1.25 + 30 * S;
divider(g, tx, by, 360 * S, 1, S);
text(g, 'TAURUS · 4.20 — 5.20', tx, by + 44 * S, { size: 30 * S, font: FONT.latin, weight: 700, color: col(C.gold), spacing: 4 * S });
if (!P) { bullSide(g, tx, H * .8, (wide ? .55 : .5) * S, { t: 2 }); }
dust(g, 2, W, H, { n: 40, alpha: .8 });
}