Install
openclaw skills install @fsyj123/canvas-poster-kitCreate production-ready single-image posters, banners, and infographics as scalable PNGs using HTML canvas with multi-resolution export and programmatic colo...
openclaw skills install @fsyj123/canvas-poster-kitDesign posters as HTML <canvas> drawings and export them at multiple resolutions from the same drawing code. Everything here was learned from shipping real posters across three production iterations (dark-tech conference poster → warm empathy poster → multi-resolution export refactor).
Canvas gives you pixel-perfect programmatic control: gradients, glow shadows, exact color zones, and a one-line PNG export (toDataURL). Choose it when the deliverable is a single static image.
#000814 bg + neon cyan) fits AI/tech; warm cream + coral fits empathy/kindness topics. See references/design-patterns.md.assets/template.html (the multi-resolution engine). Replace the placeholder draw*() sections with your content. Keep W/H as logical dimensions.references/browser-qa.md: open via headless browser, eval render checks, verify PNG signature, PIL pixel-zone sampling.Never rewrite drawing code for higher resolution. Scale the transform matrix instead:
function applyScale(scale) {
canvas.width = W * scale; // internal pixels grow
canvas.height = H * scale;
canvas.style.width = W + 'px'; // display size stays constant
canvas.style.height = H + 'px'; // → preview never jumps
ctx.setTransform(scale, 0, 0, scale, 0, 0); // all coordinates/fonts/shadows auto-scale
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
}
function download(scale) {
requestAnimationFrame(() => { // let "Rendering…" status paint first
applyScale(scale);
render(); // your existing draw functions, unchanged
const link = document.createElement('a');
link.download = `poster_${scale}x.png`;
link.href = canvas.toDataURL('image/png');
link.click();
applyScale(1); render(); // restore preview
});
}
Why this works: setTransform(scale,0,0,scale,0,0) scales the entire drawing matrix, so every coordinate, fillText size, shadowBlur and lineWidth in existing code scales N× automatically. Full details, memory limits and failure modes: references/multi-resolution.md.
After generating, verify before delivering:
JSON.stringify({w: canvas.width, h: canvas.height}) after applyScale(4); render() — expect {w: W*4, h: H*4}.toDataURL() must start with data:image/png;base64,iVBORw0K.scripts/qa_poster.py to sample expected background/accent colors at known coordinates.fillText string the user asked to include; after text-removal edits, expect zero matches for removed strings (keep surrounding shape-drawing code intact — remove only the fillText lines).User asks to remove/change specific text? grep -n "<exact string>" index.html → locate the ctx.fillText(...) call → edit/remove that line only. Never touch gradients, lines, or shape code around it. Verify with grep: zero matches post-edit.
applyScale(4), canvas.width is 4× but canvas.style.width must stay at logical size, or the page layout jumps.requestAnimationFrame or the UI freezes before the status message paints.Run before building:
agent-browser / Playwright / chromium --headlesspython3 -c "import PIL" (QA script dependency)index.html