anvilsign in

collin/mahjong · 9879b92d

Say where a wall landed, and mean it

Collin Richards · 2026-08-21 22:48 UTC · 9879b92d0c649febbcf977961bf413dfe52e2d21 · parent 40a1e457 · browse files

modifiedsrc/ui/WallRing.tsx+22 −12
⋯ 125 unchanged lines
126126 cell: number,
127127 ) {
128128 const [slide, setSlide] = useState<Nudge[]>(() => [0, 1, 2, 3].map(() => ({ along: 0, across: 0 })));
129+ // Where the walls are, as the drag knows it. React state is what draws them,
130+ // and it commits when it commits — which is one push behind if the pointer
131+ // has already gone up. This is the same thing, now.
132+ const live = useRef<Nudge[]>(slide);
129133 const drag = useRef<{
130134 side: number;
131135 ax: number;
⋯ 4 unchanged lines
136140 } | null>(null);
137141 // What the drag needs to know, kept current without the listeners below
138142 // having to be torn down and put back on every render to see it.
139- const now = useRef({ shape, cell, slide });
140- now.current = { shape, cell, slide };
143+ const now = useRef({ shape, cell });
144+ now.current = { shape, cell };
141145
142146 const moved = () => ring.current?.dispatchEvent(new CustomEvent('wallmoved', { bubbles: true }));
143147
⋯ 18 unchanged lines
162166 fromAlong: e.clientX * ax + e.clientY * ay,
163167 // Across is the wall's own normal: its direction turned a quarter on.
164168 fromAcross: -e.clientX * ay + e.clientY * ax,
165- at: now.current.slide[side],
169+ at: live.current[side],
166170 };
167171 };
168172
⋯ 10 unchanged lines
179183 along: clamp(d.at.along + (e.clientX * d.ax + e.clientY * d.ay - d.fromAlong)),
180184 across: clamp(d.at.across + (-e.clientX * d.ay + e.clientY * d.ax - d.fromAcross)),
181185 };
182- let changed = false;
183- setSlide((was) => {
184- const had = was[d.side];
185- if (had.along === to.along && had.across === to.across) return was;
186- changed = true;
187- return was.map((v, i) => (i === d.side ? to : v));
188- });
189- if (changed) moved();
186+ const had = live.current[d.side];
187+ if (had.along === to.along && had.across === to.across) return;
188+ live.current = live.current.map((v, i) => (i === d.side ? to : v));
189+ setSlide(live.current);
190+ moved();
190191 };
191192 const up = () => {
192- if (!drag.current) return;
193+ const d = drag.current;
194+ if (!d) return;
193195 drag.current = null;
194196 moved();
197+ // Said out loud at the end of the push, not during it: what the fingers
198+ // found, in the form it would be written down in.
199+ const at = live.current;
200+ const say = (n: Nudge) => `${Math.round(n.along)},${Math.round(n.across)}`;
201+ console.log(
202+ `[wall] ${WALL_SIDES[d.side]} pushed to ${say(at[d.side])} — ` +
203+ WALL_SIDES.map((cls, i) => `${cls} ${say(at[i])}`).join(' · '),
204+ );
195205 };
196206 window.addEventListener('pointermove', move);
197207 window.addEventListener('pointerup', up);
⋯ 102 unchanged lines