feat: 模板注册表 · 可扩展模板系统 · 先注册小红书 · 预留海报/即刻/通用位
This commit is contained in:
parent
fac590a3bb
commit
5785cd8895
163
image-studio/templates/registry.js
Normal file
163
image-studio/templates/registry.js
Normal file
@ -0,0 +1,163 @@
|
||||
/**
|
||||
* ═══════════════════════════════════════════════════
|
||||
* 铸渊封面工作室 · 模板注册表
|
||||
* ═══════════════════════════════════════════════════
|
||||
*
|
||||
* 所有模板在此注册。新增模板只需:
|
||||
* 1. 在 templates/ 下创建模板文件
|
||||
* 2. 在此文件 import + 注册
|
||||
* 3. 核心代码零改动
|
||||
*/
|
||||
|
||||
import { xiaohongshuCard } from './xiaohongshu.js'
|
||||
|
||||
/**
|
||||
* 模板注册表
|
||||
*/
|
||||
export const TEMPLATE_REGISTRY = {
|
||||
|
||||
xiaohongshu: {
|
||||
id: 'xiaohongshu',
|
||||
name: '小红书封面',
|
||||
description: '1080×1440 · 3:4 竖版 · 适合小红书笔记封面',
|
||||
icon: '📕',
|
||||
sizes: { width: 1080, height: 1440 },
|
||||
category: '封面',
|
||||
isDefault: true,
|
||||
instructions: '输入标题和正文,自动排版生成小红书封面。支持金句、干货列表、教程等多种布局。',
|
||||
features: ['智能排版', '金句模式', '干货列表', '多页轮播'],
|
||||
presets: [
|
||||
{
|
||||
id: 'tech',
|
||||
name: '科技蓝',
|
||||
cssVars: {
|
||||
'--bg': '#0a0e27',
|
||||
'--primary': '#e0e6ff',
|
||||
'--accent': '#4f8cff',
|
||||
'--highlight': '#00d4ff',
|
||||
'--gold': '#ffb347',
|
||||
'--warm': '#1a1f3a',
|
||||
'--text': '#c8d6e5',
|
||||
'--textMuted': '#6b7d99',
|
||||
'--cardBg': '#121838',
|
||||
'--border': '#1e2a4a',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'warm',
|
||||
name: '奶油暖调',
|
||||
cssVars: {
|
||||
'--bg': '#fef7f0',
|
||||
'--primary': '#5d4037',
|
||||
'--accent': '#e07a5f',
|
||||
'--highlight': '#d4a373',
|
||||
'--gold': '#c9a96e',
|
||||
'--warm': '#fae1dd',
|
||||
'--text': '#3e2723',
|
||||
'--textMuted': '#8d6e63',
|
||||
'--cardBg': '#ffffff',
|
||||
'--border': '#f0e6d3',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'minimal',
|
||||
name: '极简黑白',
|
||||
cssVars: {
|
||||
'--bg': '#ffffff',
|
||||
'--primary': '#111111',
|
||||
'--accent': '#333333',
|
||||
'--highlight': '#ff4757',
|
||||
'--gold': '#999999',
|
||||
'--warm': '#f5f5f5',
|
||||
'--text': '#222222',
|
||||
'--textMuted': '#888888',
|
||||
'--cardBg': '#fafafa',
|
||||
'--border': '#e0e0e0',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rose',
|
||||
name: '玫瑰粉调',
|
||||
cssVars: {
|
||||
'--bg': '#fdf2f8',
|
||||
'--primary': '#4a1942',
|
||||
'--accent': '#9d4e8d',
|
||||
'--highlight': '#e8435e',
|
||||
'--gold': '#c9a96e',
|
||||
'--warm': '#fce4ec',
|
||||
'--text': '#311b2e',
|
||||
'--textMuted': '#8e6290',
|
||||
'--cardBg': '#ffffff',
|
||||
'--border': '#f0d4e0',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'green',
|
||||
name: '文艺绿植',
|
||||
cssVars: {
|
||||
'--bg': '#f5f9f2',
|
||||
'--primary': '#1b3a1b',
|
||||
'--accent': '#5a8f5a',
|
||||
'--highlight': '#c78b5c',
|
||||
'--gold': '#b8a06e',
|
||||
'--warm': '#e8f0e0',
|
||||
'--text': '#2d3e2f',
|
||||
'--textMuted': '#6b8b6b',
|
||||
'--cardBg': '#ffffff',
|
||||
'--border': '#d4e4cc',
|
||||
},
|
||||
},
|
||||
],
|
||||
render: xiaohongshuCard,
|
||||
},
|
||||
|
||||
/* ── 后续接入(模板文件待创建时取消注释即可)── */
|
||||
// poster: { ... },
|
||||
// jike: { ... },
|
||||
// dynamic: { ... },
|
||||
}
|
||||
|
||||
|
||||
/** 获取所有可用模板列表 */
|
||||
export function listTemplates() {
|
||||
return Object.values(TEMPLATE_REGISTRY).map(t => ({
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
description: t.description,
|
||||
icon: t.icon,
|
||||
sizes: t.sizes,
|
||||
category: t.category,
|
||||
features: t.features,
|
||||
instructions: t.instructions,
|
||||
presets: t.presets.map(p => ({ id: p.id, name: p.name })),
|
||||
isDefault: t.isDefault,
|
||||
}))
|
||||
}
|
||||
|
||||
/** 获取单个模板 */
|
||||
export function getTemplate(id) {
|
||||
return TEMPLATE_REGISTRY[id] || null
|
||||
}
|
||||
|
||||
/** 获取默认模板 */
|
||||
export function getDefaultTemplate() {
|
||||
return Object.values(TEMPLATE_REGISTRY).find(t => t.isDefault)
|
||||
|| Object.values(TEMPLATE_REGISTRY)[0]
|
||||
}
|
||||
|
||||
/** 根据模板+预设+内容,准备渲染数据 */
|
||||
export function prepareRenderData(templateId, presetId, contentData) {
|
||||
const template = getTemplate(templateId)
|
||||
if (!template) return null
|
||||
|
||||
const preset = template.presets.find(p => p.id === presetId)
|
||||
|| template.presets[0]
|
||||
|
||||
return {
|
||||
...contentData,
|
||||
templateId,
|
||||
presetId: preset?.id || 'default',
|
||||
cssVars: preset?.cssVars || {},
|
||||
sizes: template.sizes,
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user