Feature graphic fits the phone: shots.feature.fit 'contain' (default) sizes the device so its rotated box stays inside 1024x500 with a 24 px margin in both templates, 'bleed' keeps the crop, scale 0.5-1.5, config validated; shots render records measured device boxes (report.json devices) and shots check fails a feature graphic whose device leaves the canvas (warns for a screenshot's front device off a side or the top); tests/feature-fit.test.ts (rotated-box geometry, both templates rendered at 1024x500, bleeding fixture) (pitfall 55)

This commit is contained in:
CRTkafa 2026-10-13 09:49:53 +08:00
parent 6e2dbf03cc
commit 19d34286d5
15 changed files with 239 additions and 12 deletions

View file

@ -41,12 +41,18 @@ R.setProperty('--ar', `${dev.w} / ${dev.h + dev.bar}`);
R.setProperty('--appH', `${100 * dev.h / (dev.h + dev.bar)}%`);
R.setProperty('--barH', `${100 * dev.bar / (dev.h + dev.bar)}%`);
const c = document.getElementById('c');
// device place and size from featureLayout() (lib.ts): fit 'contain' keeps the rotated phone inside the canvas
const D = job.device, tel = c.querySelector('.tel');
if (D) Object.assign(tel.style, { left: D.left + 'px', top: D.top + 'px', width: D.width + 'px', transform: `rotate(${D.angle}deg)` });
const src = `/frames/${encodeURIComponent(lang)}/phone/${encodeURIComponent(job.frame)}`;
document.getElementById('f').src = src;
document.getElementById('bar').style.backgroundImage = `url('${src}')`;
c.insertAdjacentHTML('beforeend', job.logo ? '<img class="logo" src="/logo">' : `<div class="name">${String(job.appName).replace(/</g, '&lt;')}</div>`);
await document.fonts.ready;
await Promise.all([...document.images].map(i => i.decode().catch(() => {})));
// read by `shots render` -> report.json -> shots check: the phone's rotated outline must stay inside the canvas
document.body.dataset.devices = JSON.stringify([...c.querySelectorAll('.tel')].map(t => { const r = t.getBoundingClientRect(); return { x: r.x, y: r.y, w: r.width, h: r.height }; }));
if (D?.fit === 'bleed') document.body.dataset.bleed = '1';
document.body.dataset.ready = '1';
</script>
</body>