Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/dev/shot_permchip_ladder.mjs

2.8 KiB, 1 run

created by r2519314175:169, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1// shot_permchip_ladder.mjs — the same chip at several nudges, 8x, stacked.
2//
3// The numbers in shot_permchip.mjs say where each band is; they cannot say which
4// band looks right, and that is a judgement that has to be made by looking. This
5// renders the chip at a ladder of offsets, magnifies each nearest-neighbour, and
6// stacks them with their values, for each of the three labels in turn.
7//
8// node dev/shot_permchip_ladder.mjs → dev/shots/permchip-ladder.png
9import fs from 'node:fs';
10import path from 'node:path';
11import { fileURLToPath } from 'node:url';
12import { open, chat } from './harness.mjs';
13
14const HERE = path.dirname(fileURLToPath(import.meta.url));
15const SHOTS = path.join(HERE, 'shots');
16fs.mkdirSync(SHOTS, { recursive: true });
17
18const NUDGES = [-0.5, 0, 0.25, 0.5, 1];
19const LABELS = ['Guarded', 'Bypass', 'Ask every time'];
20
21const s = await open({ name: 'permladder' });
22const p = s.page;
23await chat(s, '@text hello');
24
25const shots = [];
26for (const label of LABELS) {
27 for (const n of NUDGES) {
28 await p.evaluate(({ label, n }) => {
29 document.getElementById('hand-mode-chip-txt').textContent = label;
30 document.querySelector('.mode-chip-dot').style.transform = `translateY(${n}px)`;
31 }, { label, n });
32 await p.waitForTimeout(80);
33 shots.push({ label, n, png: (await p.locator('#hand-mode-chip').screenshot()).toString('base64') });
34 }
35}
36// Put the chip back the way the stylesheet has it.
37await p.evaluate(() => {
38 document.querySelector('.mode-chip-dot').style.transform = '';
39 document.getElementById('hand-mode-chip-txt').textContent = 'Guarded';
40});
41
42await p.evaluate(async (shots) => {
43 const imgs = [];
44 for (const s of shots) {
45 const im = new Image();
46 await new Promise((res) => { im.onload = res; im.src = 'data:image/png;base64,' + s.png; });
47 imgs.push(im);
48 }
49 const S = 8, PAD = 10, LAB = 130;
50 const w = LAB + Math.max(...imgs.map(i => i.width)) * S + PAD * 2;
51 const h = imgs.reduce((a, i) => a + i.height * S + PAD, PAD);
52 const c = document.createElement('canvas');
53 c.id = '__ladder'; c.width = w; c.height = h;
54 c.style.cssText = 'position:fixed;left:0;top:0;z-index:99999;';
55 const g = c.getContext('2d');
56 g.imageSmoothingEnabled = false;
57 g.fillStyle = '#606060'; g.fillRect(0, 0, w, h);
58 let y = PAD;
59 imgs.forEach((im, i) => {
60 g.drawImage(im, LAB, y, im.width * S, im.height * S);
61 g.fillStyle = '#fff'; g.font = '16px monospace';
62 g.fillText(`${shots[i].n >= 0 ? '+' : ''}${shots[i].n}px`, 8, y + 24);
63 g.fillText(shots[i].label.slice(0, 9), 8, y + 44);
64 // A hairline through the middle of each strip, so the eye has a datum.
65 y += im.height * S + PAD;
66 });
67 document.body.appendChild(c);
68}, shots);
69await p.locator('#__ladder').screenshot({ path: path.join(SHOTS, 'permchip-ladder.png') });
70await s.close();
71console.log('wrote dev/shots/permchip-ladder.png');