Keyboard Shortcuts
The engine doesn’t synthesize keyboard events, so bind a keydown listener on the window
yourself and route keys to the History. This recipe adds undo/redo,
delete, and arrow-key nudging that act on the current SelectionController selection — every
change is undoable because it goes through a command.
import { Stage, History, SelectionController, RemoveNodeCommand, SetPropsCommand, CompositeCommand, Rect,} from '@veyrajs/core'
const stage = new Stage({ container: document.getElementById('app')!, width: 800, height: 480 })const layer = stage.createLayer()layer.add(new Rect({ x: 120, y: 100, width: 150, height: 90, fill: '#38bdf8' }))
const history = new History()const controller = new SelectionController(stage, { history })
const NUDGE: Record<string, [number, number]> = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1],}
function onKeyDown(e: KeyboardEvent) { const mod = e.ctrlKey || e.metaKey const selected = [...controller.selection.nodes] // snapshot before mutating
if (mod && e.key.toLowerCase() === 'z') { e.preventDefault() if (e.shiftKey) history.redo() else history.undo() return }
if (e.key === 'Delete' || e.key === 'Backspace') { if (!selected.length) return e.preventDefault() history.run(new CompositeCommand(selected.map((n) => new RemoveNodeCommand(n)), 'delete')) controller.selection.clear() return }
const delta = NUDGE[e.key] if (delta && selected.length) { e.preventDefault() const step = e.shiftKey ? 10 : 1 const [dx, dy] = delta history.run(new CompositeCommand( selected.map((n) => new SetPropsCommand( n, { x: n.x, y: n.y }, { x: n.x + dx * step, y: n.y + dy * step }, 'nudge', )), 'nudge', )) }}
window.addEventListener('keydown', onKeyDown)// Teardown: window.removeEventListener('keydown', onKeyDown)history.run(command) applies a command and records it, so undo/redo come for free.
SetPropsCommand captures before/after values (not deltas), and wrapping a batch in a
CompositeCommand makes a multi-node nudge or delete reverse in a single undo. Hold Shift with
an arrow for a bigger 10 px step. Note that RemoveNodeCommand’s undo re-adds the node at the
top of the z-order.