Add PNG sequence export and uuid-keyed stage placements
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016JBYKfeMPQTK1WNcgcw41o
This commit is contained in:
parent
3058b9a5f2
commit
e22ee600b9
31 changed files with 2642 additions and 178 deletions
|
|
@ -404,8 +404,13 @@ async function main() {
|
|||
check(stageLoaded !== null, 'the 8625 stage is ready', stageLoaded ?? (await page.eval(STATUS)));
|
||||
const eyeSelected = await page.eval(`(() => {
|
||||
const select = document.querySelector('.controls select');
|
||||
// The instance prefix is the placement's NAME ("8625 left"), not its id:
|
||||
// a placement is keyed by a uuid now, and a uuid is not something to show
|
||||
// anyone. So this matches the feature and requires SOME instance prefix,
|
||||
// rather than pinning the label a rename is free to change.
|
||||
const option = [...select.options]
|
||||
.find(o => o.textContent.trim() === 'left / feature · eye-r');
|
||||
.find(o => o.textContent.trim().endsWith('/ feature · eye-r')
|
||||
&& o.textContent.includes(' / '));
|
||||
if (!option) return false;
|
||||
select.value = option.value;
|
||||
select.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
|
|
@ -417,6 +422,12 @@ async function main() {
|
|||
const row = [...document.querySelectorAll('.control-row')]
|
||||
.find(row => row.querySelector('span')?.textContent === 'iris-size');
|
||||
if (!row) return null;
|
||||
// Scrolled into view FIRST, because the click below is dispatched at
|
||||
// viewport coordinates: a control panel that has grown past the fold
|
||||
// otherwise reports a y outside the window, the click lands on nothing,
|
||||
// and the failure reads as "regeneration is broken" rather than "the
|
||||
// slider was off-screen". Which is exactly what it read as once.
|
||||
row.scrollIntoView({ block: 'center' });
|
||||
const r = row.querySelector('input').getBoundingClientRect();
|
||||
return { x: r.x + r.width * 0.9, y: r.y + r.height / 2 };
|
||||
})()`);
|
||||
|
|
@ -455,6 +466,12 @@ async function main() {
|
|||
const row = [...document.querySelectorAll('.control-row')]
|
||||
.find(row => row.querySelector('span')?.textContent === 'anchor-avg');
|
||||
if (!row) return null;
|
||||
// Scrolled into view FIRST, because the click below is dispatched at
|
||||
// viewport coordinates: a control panel that has grown past the fold
|
||||
// otherwise reports a y outside the window, the click lands on nothing,
|
||||
// and the failure reads as "regeneration is broken" rather than "the
|
||||
// slider was off-screen". Which is exactly what it read as once.
|
||||
row.scrollIntoView({ block: 'center' });
|
||||
const r = row.querySelector('input').getBoundingClientRect();
|
||||
return { x: r.x + r.width * 0.9, y: r.y + r.height / 2 };
|
||||
})()`);
|
||||
|
|
@ -485,7 +502,8 @@ async function main() {
|
|||
const teethSelected = await page.eval(`(() => {
|
||||
const select = document.querySelector('.controls select');
|
||||
const option = [...select.options]
|
||||
.find(o => o.textContent.trim() === 'left / feature · teeth');
|
||||
.find(o => o.textContent.trim().endsWith('/ feature · teeth')
|
||||
&& o.textContent.includes(' / '));
|
||||
if (!option) return false;
|
||||
select.value = option.value;
|
||||
select.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
|
|
@ -498,6 +516,12 @@ async function main() {
|
|||
const row = [...document.querySelectorAll('.control-row')]
|
||||
.find(row => row.querySelector('span')?.textContent === 'cavity-erode');
|
||||
if (!row) return null;
|
||||
// Scrolled into view FIRST, because the click below is dispatched at
|
||||
// viewport coordinates: a control panel that has grown past the fold
|
||||
// otherwise reports a y outside the window, the click lands on nothing,
|
||||
// and the failure reads as "regeneration is broken" rather than "the
|
||||
// slider was off-screen". Which is exactly what it read as once.
|
||||
row.scrollIntoView({ block: 'center' });
|
||||
const r = row.querySelector('input').getBoundingClientRect();
|
||||
return { x: r.x + r.width * 0.9, y: r.y + r.height / 2 };
|
||||
})()`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue