Files
2026-01-28 19:33:35 +13:00

85 lines
3.2 KiB
JavaScript

/**
* Keyboard event handlers
*/
/**
* Create keyboard event handler
* @param {HTMLElement} container - Container element
* @param {Object} state - Editor state
* @param {Object} callbacks - Callback functions
* @param {Function} callbacks.setMode - Set editor mode
* @param {Function} callbacks.getActiveShape - Get active shape
* @param {Function} callbacks.promoteToKeyframe - Promote to keyframe
* @param {Function} callbacks.commitFrame - Commit frame
* @param {Function} callbacks.redraw - Redraw canvas
* @param {Function} callbacks.removeDocumentListeners - Remove document listeners
* @param {Function} callbacks.updateAddPointButton - Update add point button
*/
export function createKeyboardHandlers(container, state, callbacks) {
function handleKeydown(e) {
// Only handle if not typing in an input
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") {
return;
}
if (e.key === "b" || e.key === "B") {
state.selectedCurves.clear();
state.selectedPoints.clear();
callbacks.setMode("draw");
e.preventDefault();
} else if (e.key === "v" || e.key === "V") {
callbacks.setMode("edit");
e.preventDefault();
} else if (e.key === "Delete" || e.key === "Backspace") {
if (state.mode === "edit" && state.selectedCurves.size > 0) {
const shape = callbacks.getActiveShape();
const frameKey = String(state.currentFrame);
// Promote only the selected curves to be deleted
state.selectedCurves.forEach(curveId => {
callbacks.promoteToKeyframe(curveId);
});
const curves = shape.frames[frameKey] || [];
state.selectedCurves.forEach(curveId => {
const index = curves.findIndex(c => c.id === curveId);
if (index !== -1) {
curves.splice(index, 1);
}
});
state.selectedCurves.clear();
state.selectedPoints.clear();
callbacks.commitFrame();
callbacks.redraw();
e.preventDefault();
}
} else if (e.key === "Escape") {
// Cancel selection box if active
if (state.selectionBox !== null) {
state.selectionBox = null;
}
// Cancel add point mode if active
if (state.addPointMode) {
state.addPointMode = false;
callbacks.updateAddPointButton();
}
// Cancel dragging if active
if (state.dragging) {
state.dragging = false;
state.dragStart = null;
callbacks.removeDocumentListeners();
}
state.selectedCurves.clear();
state.selectedPoints.clear();
callbacks.redraw();
e.preventDefault();
}
}
// Keyboard shortcuts (scoped to container, with document fallback)
container.addEventListener("keydown", handleKeydown);
document.addEventListener("keydown", handleKeydown);
}