34 lines
3.7 KiB
JavaScript
Raw Permalink Normal View History

const FONT = "'Noto Sans CJK SC','WenQuanYi Micro Hei',sans-serif"
export function renderComponents(config) {
const { canvas:cv={}, stack=[] } = config
const W=cv.width||1080, H=cv.height||1440, bg=cv.bg||'#FDF8F3'
let css=`*{margin:0;padding:0;box-sizing:border-box}body{width:${W}px;height:${H}px;overflow:hidden;font-family:${FONT};background:${bg};display:flex;justify-content:center;align-items:center}`
css+=`.card{border-radius:60px;box-shadow:0 20px 80px rgba(0,0,0,.06);background:#fff;display:flex;flex-direction:column;width:960px;height:1320px;padding:60px 70px 50px;position:relative}`
css+=`.deco{position:absolute;border-radius:50%}.deco-tr{top:-100px;right:-80px;width:320px;height:320px;background:radial-gradient(circle,rgba(224,123,57,.08),transparent 70%)}.deco-bl{bottom:200px;left:-60px;width:180px;height:180px;background:radial-gradient(circle,rgba(74,144,164,.06),transparent 70%)}`
css+=`.badge{display:inline-flex;padding:10px 24px;border-radius:24px;font-size:20px;font-weight:800}.badge-a{background:rgba(224,123,57,.12);color:#2D5016;border:2px solid rgba(224,123,57,.25)}.badge-n{background:#FDF8F3;color:#2D5016;border:2px solid rgba(224,123,57,.12)}`
css+=`.th1{font-size:68px;font-weight:900;line-height:1.15;letter-spacing:2px;margin-bottom:16px}.tl{display:block}.td{color:#1A1A1A}.tg{color:#2D5016}.to{color:#E07B39}`
css+=`.pw{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:40px}.pi{display:inline-block;padding:8px 20px;border-radius:24px;font-size:20px;font-weight:700}.pz{background:#2D5016;color:#fff;font-size:24px}.pn{background:rgba(224,123,57,.08);color:#E07B39}`
css+=`.tg{display:flex;gap:16px;margin-bottom:24px}.tc{flex:1;background:#FDF8F3;border-radius:20px;padding:24px 16px;text-align:center}.tci{font-size:36px;margin-bottom:10px}.tcn{font-size:18px;font-weight:700;color:#1A1A1A;margin-bottom:4px}.tcd{font-size:14px;color:#8B8680;margin-top:4px}.tcp{font-size:22px;font-weight:900;color:#E07B39;margin-top:8px}`
css+=`.bs{text-align:center;padding:28px;background:linear-gradient(135deg,rgba(224,123,57,.06),rgba(45,80,22,.06));border-radius:24px;margin-top:auto}.bm{font-size:56px;font-weight:900;color:#E07B39;line-height:1}.bsb{font-size:18px;color:#8B8680;margin-top:8px}`
css+=`.tr{display:flex;gap:12px;margin-bottom:30px;align-items:center}`
let body='',inCard=false
for(const c of stack){
const p=c.params||{}
switch(c.component){
case'card':body+='<div class="card">';inCard=true;break
case'decor':
if(p.side==='top-right'||p.side==='both')body+='<div class="deco deco-tr"></div>'
if(p.side==='bottom-left'||p.side==='both')body+='<div class="deco deco-bl"></div>';break
case'badge':body+=`<span class="badge badge-${p.style==='normal'?'n':'a'}">${p.text||''}</span>`;break
case'topRow':body+='<div class="tr">';break
case'title':{const l=p.lines||[],co=p.colors||l.map(()=>'d');body+='<div class="th1">';l.forEach((x,i)=>body+=`<span class="tl t${co[i]||'d'}">${x}</span>`);body+='</div>';break}
case'pills':{const it=p.items||[],zz=p.zeros||[];body+='<div class="pw">';it.forEach((t,i)=>body+=`<span class="pi ${zz.includes(i)?'pz':'pn'}">${t}</span>`);body+='</div>';break}
case'toolCards':{const tc=p.items||[];body+='<div class="tg">';tc.forEach(t=>body+=`<div class="tc"><div class="tci">${t[0]||''}</div><div class="tcn">${t[1]||''}</div><div class="tcd">${t[2]||''}</div><div class="tcp">${t[3]||''}</div></div>`);body+='</div>';break}
case'bigText':body+=`<div class="bs"><div class="bm">${p.main||''}</div>`;if(p.sub)body+=`<div class="bsb">${p.sub}</div>`;body+='</div>';break
}
}
if(inCard)body+='</div>'
return`<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8"><style>${css}</style></head><body>${body}</body></html>`
}