191 lines
4.0 KiB
JavaScript
191 lines
4.0 KiB
JavaScript
|
|
/**
|
|||
|
|
* ═══════════════════════════════════════════════════
|
|||
|
|
* 即刻卡片模板 · 1080×1080 (1:1)
|
|||
|
|
* ═══════════════════════════════════════════════════
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { STYLES } from '../config.js'
|
|||
|
|
|
|||
|
|
const W = STYLES.sizes.jike.width
|
|||
|
|
const H = STYLES.sizes.jike.height
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 生成即刻卡片 HTML
|
|||
|
|
* @param {object} data
|
|||
|
|
* @param {string} data.title - 标题/核心观点
|
|||
|
|
* @param {string} data.body - 正文
|
|||
|
|
* @param {string} data.meta - 元信息(如「2026-05 · 思考碎片」)
|
|||
|
|
* @param {string} data.emoji - 封面 emoji(可选)
|
|||
|
|
* @param {'default'|'quote'|'minimal'} data.layout - 布局
|
|||
|
|
*/
|
|||
|
|
export function jikeCard(data) {
|
|||
|
|
const {
|
|||
|
|
title = '',
|
|||
|
|
body = '',
|
|||
|
|
meta = '',
|
|||
|
|
emoji = '',
|
|||
|
|
layout = 'default',
|
|||
|
|
} = data
|
|||
|
|
|
|||
|
|
const C = STYLES.colors
|
|||
|
|
const F = STYLES.fonts
|
|||
|
|
const T = STYLES.typography
|
|||
|
|
|
|||
|
|
const bodyLines = body.split('\n').filter(Boolean)
|
|||
|
|
const bodyHtml = bodyLines.map(line => `<p>${line}</p>`).join('\n')
|
|||
|
|
|
|||
|
|
return `<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<style>
|
|||
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|||
|
|
|
|||
|
|
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap');
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
width: ${W}px;
|
|||
|
|
height: ${H}px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
background: ${C.bg};
|
|||
|
|
font-family: ${F.body};
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 顶部渐变装饰条 */
|
|||
|
|
.accent-bar {
|
|||
|
|
height: 6px;
|
|||
|
|
background: linear-gradient(90deg, ${C.accent}, ${C.highlight}, ${C.gold});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.container {
|
|||
|
|
flex: 1;
|
|||
|
|
padding: 48px 56px;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.meta {
|
|||
|
|
font-size: ${T.captionSize}px;
|
|||
|
|
color: ${C.textMuted};
|
|||
|
|
letter-spacing: 2px;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.emoji-row {
|
|||
|
|
font-size: 64px;
|
|||
|
|
margin-bottom: 16px;
|
|||
|
|
line-height: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.title {
|
|||
|
|
font-family: ${F.title};
|
|||
|
|
font-size: 40px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
line-height: 1.4;
|
|||
|
|
color: ${C.primary};
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
letter-spacing: 1px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.body {
|
|||
|
|
flex: 1;
|
|||
|
|
font-size: 26px;
|
|||
|
|
line-height: 1.7;
|
|||
|
|
color: ${C.text};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.body p {
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 金句布局 */
|
|||
|
|
.quote-section {
|
|||
|
|
flex: 1;
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
justify-content: center;
|
|||
|
|
align-items: center;
|
|||
|
|
text-align: center;
|
|||
|
|
padding: 0 32px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quote-emoji {
|
|||
|
|
font-size: 72px;
|
|||
|
|
margin-bottom: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quote-line {
|
|||
|
|
width: 40px;
|
|||
|
|
height: 2px;
|
|||
|
|
background: ${C.gold};
|
|||
|
|
margin: 0 auto 24px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quote-title {
|
|||
|
|
font-family: ${F.title};
|
|||
|
|
font-size: 36px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
color: ${C.primary};
|
|||
|
|
letter-spacing: 2px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.quote-body {
|
|||
|
|
margin-top: 20px;
|
|||
|
|
font-size: 24px;
|
|||
|
|
color: ${C.textMuted};
|
|||
|
|
line-height: 1.6;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 底部 */
|
|||
|
|
.footer {
|
|||
|
|
padding: 20px 56px 28px;
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
align-items: center;
|
|||
|
|
border-top: 1px solid ${C.divider};
|
|||
|
|
font-size: ${T.captionSize}px;
|
|||
|
|
color: ${C.textMuted};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand {
|
|||
|
|
opacity: ${STYLES.brand.opacity};
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
|
|||
|
|
<div class="accent-bar"></div>
|
|||
|
|
|
|||
|
|
<div class="container">
|
|||
|
|
|
|||
|
|
${meta ? `<div class="meta">${meta}</div>` : ''}
|
|||
|
|
|
|||
|
|
${layout === 'quote' ? `
|
|||
|
|
<div class="quote-section">
|
|||
|
|
${emoji ? `<div class="quote-emoji">${emoji}</div>` : ''}
|
|||
|
|
<div class="quote-line"></div>
|
|||
|
|
<div class="quote-title">${title}</div>
|
|||
|
|
${body ? `<div class="quote-body">${body}</div>` : ''}
|
|||
|
|
</div>
|
|||
|
|
` : `
|
|||
|
|
${emoji ? `<div class="emoji-row">${emoji}</div>` : ''}
|
|||
|
|
<div class="title">${title}</div>
|
|||
|
|
<div class="body">${bodyHtml}</div>
|
|||
|
|
`}
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="footer">
|
|||
|
|
<span class="brand">${STYLES.brand.text}</span>
|
|||
|
|
<span>即刻 · Jike</span>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
</body>
|
|||
|
|
</html>`
|
|||
|
|
}
|