Skip to content

Commit ea7cb00

Browse files
russellashbyclaude
andcommitted
Add arrow key polygon movement
Arrow keys translate all vertices by 1 grid unit, clamped to grid bounds. New translateVertices pure function in vector.js with 4 test suites (61 total tests passing). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 50a31ba commit ea7cb00

3 files changed

Lines changed: 48 additions & 2 deletions

File tree

index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,14 @@ <h2>Lua Output</h2>
721721
if (e.key === 'c' && !e.ctrlKey && !e.metaKey) {
722722
document.getElementById('closeBtn').click();
723723
}
724+
// Arrow keys to move closed polygon
725+
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key) && vertices.length > 0) {
726+
e.preventDefault();
727+
const dx = e.key === 'ArrowLeft' ? -1 : e.key === 'ArrowRight' ? 1 : 0;
728+
const dy = e.key === 'ArrowUp' ? -1 : e.key === 'ArrowDown' ? 1 : 0;
729+
vertices = translateVertices(vertices, dx, dy, gridSize);
730+
refresh();
731+
}
724732
});
725733

726734
// Init

tests.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { gridToCanvas, canvasToGrid, rotatePoint, getEffectiveVertices, parseLuaTable, generateLuaOutput } = require('./vector.js');
1+
const { gridToCanvas, canvasToGrid, rotatePoint, getEffectiveVertices, parseLuaTable, generateLuaOutput, translateVertices } = require('./vector.js');
22

33
let passed = 0;
44
let failed = 0;
@@ -227,6 +227,36 @@ suite('generateLuaOutput -> parseLuaTable roundtrip', () => {
227227
}
228228
});
229229

230+
// ── translateVertices ──
231+
232+
suite('translateVertices — basic move', () => {
233+
const verts = [[0, 0], [2, 3]];
234+
const moved = translateVertices(verts, 1, -1, 32);
235+
assert(moved[0][0] === 1 && moved[0][1] === -1, 'first vertex moved');
236+
assert(moved[1][0] === 3 && moved[1][1] === 2, 'second vertex moved');
237+
});
238+
239+
suite('translateVertices — clamping to grid bounds', () => {
240+
const verts = [[15, 15]];
241+
const moved = translateVertices(verts, 5, 5, 32);
242+
assert(moved[0][0] === 16 && moved[0][1] === 16, 'clamped to grid half');
243+
244+
const moved2 = translateVertices([[-15, -15]], -5, -5, 32);
245+
assert(moved2[0][0] === -16 && moved2[0][1] === -16, 'clamped to negative bound');
246+
});
247+
248+
suite('translateVertices — zero movement', () => {
249+
const verts = [[3, 4]];
250+
const moved = translateVertices(verts, 0, 0, 32);
251+
assert(moved[0][0] === 3 && moved[0][1] === 4, 'unchanged');
252+
});
253+
254+
suite('translateVertices — does not mutate original', () => {
255+
const verts = [[1, 2]];
256+
translateVertices(verts, 5, 5, 32);
257+
assert(verts[0][0] === 1 && verts[0][1] === 2, 'original unchanged');
258+
});
259+
230260
// ── Summary ──
231261

232262
console.log(`\n${'='.repeat(40)}`);

vector.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ function generateLuaOutput(vertices, scaleFactor) {
102102
return lua;
103103
}
104104

105+
function translateVertices(vertices, dx, dy, gridSize) {
106+
const half = gridSize / 2;
107+
return vertices.map(([x, y]) => [
108+
Math.max(-half, Math.min(half, x + dx)),
109+
Math.max(-half, Math.min(half, y + dy))
110+
]);
111+
}
112+
105113
if (typeof module !== 'undefined' && module.exports) {
106-
module.exports = { gridToCanvas, canvasToGrid, rotatePoint, getEffectiveVertices, parseLuaTable, generateLuaOutput };
114+
module.exports = { gridToCanvas, canvasToGrid, rotatePoint, getEffectiveVertices, parseLuaTable, generateLuaOutput, translateVertices };
107115
}

0 commit comments

Comments
 (0)