Files

18 lines
3.7 KiB
HTML

<!doctype html><html><meta charset="utf-8"><title>Poster design validation</title><style>body{font:14px system-ui;background:#eef0f3}#results{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}article{padding:10px;background:white}img{width:100%}pre{white-space:pre-wrap}</style><h1>Real template rendering and persistence check</h1><output id="summary">Running</output><pre id="errors"></pre><div id="results"></div><script type="module">
import {buildPosterDesign,DESIGN_TEMPLATES,PLATFORMS} from '/src/lib/poster-design/templates.ts';
import {posterObject,posterElementFromObject,renderPosterThumbnail,ensurePosterContrast,ActiveSelection,Canvas} from '/src/lib/poster-canvas.ts';
import {parsePosterDocument,serializePosterDocument} from '@edgeever/shared';
let passed=0,failed=0;const errors=[];
for(const size of PLATFORMS.map(({width,height})=>({width,height})))for(const template of DESIGN_TEMPLATES){try{
const doc=await buildPosterDesign({id:template.id,title:'把想法\n变成作品',subtitle:'认真记录,让每个好想法被看见。',badge:'创作笔记',...size,zh:true});
const parsed=parsePosterDocument(serializePosterDocument(doc));if(JSON.stringify(parsed)!==JSON.stringify(doc))throw new Error('source roundtrip differs');
const src=await renderPosterThumbnail(doc);passed++;if(size.width===1080&&size.height===1440){const item=document.createElement('article');item.innerHTML=`<img src="${src}"><p>${template.zh} · ${doc.elements.length}</p>`;document.querySelector('#results').append(item)}else URL.revokeObjectURL(src);
}catch(error){failed++;errors.push(template.id+' '+size.width+'x'+size.height+': '+error.message);document.querySelector('#errors').textContent=errors.join('\n')}
document.querySelector('#summary').textContent=`${passed} passed, ${failed} failed`;
}
// Persisted geometry must match the world coordinates of an active multi-selection.
try{const canvas=new Canvas(document.createElement('canvas'),{width:1080,height:1440});const doc=await buildPosterDesign({id:'folio',title:'几何验证',subtitle:'保存前后保持排版',width:1080,height:1440,zh:true});const es=doc.elements.filter(e=>e.type==='text').slice(0,2);const os=await Promise.all(es.map(e=>posterObject(e,async()=>{throw Error('unexpected resource')})));canvas.add(...os);const before=os.map(o=>o.calcTransformMatrix());const group=new ActiveSelection(os,{canvas});canvas.setActiveObject(group);group.set({left:group.left+100,top:group.top+50,angle:15,scaleX:1.2,scaleY:1.2});for(let i=0;i<os.length;i++){const next=posterElementFromObject(es[i],os[i]);const restored=await posterObject(next,async()=>{throw Error('unexpected resource')});const a=os[i].calcTransformMatrix(),b=restored.calcTransformMatrix();if(a.some((v,j)=>Math.abs(v-b[j])>1.5))throw Error('multi-selection transform differs '+JSON.stringify({a,b,next}));}await canvas.dispose();passed++;}catch(e){failed++;errors.push(e.message);document.querySelector('#errors').textContent=errors.join('\n')}
try { const input=await buildPosterDesign({id:'window',title:'对比度验证',subtitle:'白色卡片上的文字必须可读',badge:'EDGE EVER',width:1080,height:1440,zh:true,palette:{bg:'#0b163b',ink:'#ffffff',accent:'#2563eb'}});const fixed=await ensurePosterContrast(input,async()=>{throw Error('unexpected image')});const title=fixed.elements.find(e=>e.type==='text'&&e.role==='title');if(!title||title.fill==='#ffffff')throw Error('AI contrast not corrected');if(input.elements.length!==fixed.elements.length)throw Error('contrast check changed structure');passed++;}catch(e){failed++;errors.push(e.message);document.querySelector('#errors').textContent=errors.join('\n')}
document.querySelector('#summary').textContent=`DONE: ${passed} passed, ${failed} failed`;
</script></html>