product page

This commit is contained in:
Felix Klement committed 2026-09-19 11:18:31 +02:00
1 parent e652b54319
commit c4513588b1
6 files changed
+332 -269

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
import { chromium } from 'playwright';
/* Does the panel start at the title and end with the list, and hold that box across steps? */
const [,, url, prefix, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const count = await page.evaluate(() => document.querySelectorAll('[data-trigger]').length);
const rows = [];
for (let i = 0; i < count; i++) {
await page.evaluate((i) => {
const t = document.querySelectorAll('[data-trigger]')[i];
const r = t.getBoundingClientRect();
window.scrollTo(0, window.scrollY + r.top + r.height / 2 - window.innerHeight / 2);
}, i);
await page.waitForTimeout(900);
rows.push(await page.evaluate(() => {
const title = document.querySelector('.how__title').getBoundingClientRect();
const steps = Array.from(document.querySelectorAll('[data-step]'));
const last = steps[steps.length - 1].getBoundingClientRect();
const fig = document.querySelector('[data-figure][data-active]').getBoundingClientRect();
const sticky = document.querySelector('.how__sticky').getBoundingClientRect();
const container = document.querySelector('.how__sticky');
const cs = getComputedStyle(container);
const rightEdge = sticky.right - parseFloat(cs.paddingRight);
return {
active: steps.findIndex((s) => s.hasAttribute('data-active')),
panel: `${Math.round(fig.width)}x${Math.round(fig.height)}`,
topVsTitle: Math.round(fig.top - title.top),
bottomVsList: Math.round(fig.bottom - last.bottom),
rightVsEdge: Math.round(fig.right - rightEdge),
listFits: Math.round(sticky.bottom - last.bottom),
};
}));
await page.screenshot({ path: `${prefix}-${i}.png` });
}
console.table(rows);
await browser.close();
+40
View File
@@ -0,0 +1,40 @@
import { chromium } from 'playwright';
/* Walks the pinned section step by step: which step is active, does the text column fit
inside the pinned area, and is the panel where it should be. */
const [,, url, prefix, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const count = await page.evaluate(() => document.querySelectorAll('[data-trigger]').length);
const rows = [];
for (let i = 0; i < count; i++) {
await page.evaluate((i) => {
const t = document.querySelectorAll('[data-trigger]')[i];
const r = t.getBoundingClientRect();
window.scrollTo(0, window.scrollY + r.top + r.height / 2 - window.innerHeight / 2);
}, i);
await page.waitForTimeout(900);
const info = await page.evaluate(() => {
const steps = Array.from(document.querySelectorAll('[data-step]'));
const active = steps.findIndex((s) => s.hasAttribute('data-active'));
const sticky = document.querySelector('.how__sticky').getBoundingClientRect();
const text = document.querySelector('.how__text');
const first = text.getBoundingClientRect();
const last = steps[steps.length - 1].getBoundingClientRect();
const fig = document.querySelector('[data-figure][data-active]');
const f = fig ? fig.getBoundingClientRect() : null;
const svg = fig ? fig.querySelector('svg').getBoundingClientRect() : null;
return {
active,
textTop: Math.round(first.top - sticky.top),
spaceBelowList: Math.round(sticky.bottom - last.bottom),
panel: f ? `${Math.round(f.width)}x${Math.round(f.height)}` : null,
drawing: svg ? `${Math.round(svg.width)}x${Math.round(svg.height)}` : null,
panelInside: f ? (f.top >= sticky.top - 1 && f.bottom <= sticky.bottom + 1) : null,
};
});
rows.push({ step: i, ...info });
await page.screenshot({ path: `${prefix}-${i}.png` });
}
console.table(rows);
await browser.close();
+24
View File
@@ -0,0 +1,24 @@
import { chromium } from 'playwright';
/* Does the pinned panel hold from the first step to the last, and let go cleanly after? */
const [,, url, prefix, width = '1440', height = '900'] = process.argv;
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: Number(width), height: Number(height) } });
await page.goto(url, { waitUntil: 'networkidle' });
const geo = await page.evaluate(() => {
const sc = document.querySelector('.how__scroller').getBoundingClientRect();
return { top: Math.round(sc.top + window.scrollY), height: Math.round(sc.height) };
});
const marks = { 'enter': geo.top, 'mid': geo.top + geo.height / 2, 'lastStep': geo.top + geo.height - (window?.innerHeight ?? 900), 'exit': geo.top + geo.height - 200 };
for (const [name, y] of Object.entries(marks)) {
await page.evaluate((y) => window.scrollTo(0, y), y);
await page.waitForTimeout(800);
const info = await page.evaluate(() => {
const st = document.querySelector('.how__sticky').getBoundingClientRect();
const active = Array.from(document.querySelectorAll('[data-step]')).findIndex((s) => s.hasAttribute('data-active'));
return { stickyTop: Math.round(st.top), stickyBottom: Math.round(st.bottom), active };
});
console.log(name.padEnd(9), JSON.stringify(info));
await page.screenshot({ path: `${prefix}-${name}.png` });
}
console.log('scroller', JSON.stringify(geo));
await browser.close();