From f2b9d000990758bdd9d221a2f408395d7041f77a Mon Sep 17 00:00:00 2001 From: Smitty Date: Mon, 12 Apr 2021 16:57:07 -0400 Subject: [PATCH] option to snap to grid --- public/index.html | 7 ++++++- public/script.js | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 3a60fae..7b6dd3d 100644 --- a/public/index.html +++ b/public/index.html @@ -204,13 +204,18 @@ + diff --git a/public/script.js b/public/script.js index 9135beb..78347bc 100644 --- a/public/script.js +++ b/public/script.js @@ -6,12 +6,15 @@ let can, ctx, gridCan, gridCtx; let state = { ihat: [1, 0], jhat: [0, 1], + ihatUnsnapped: null, + jhatUnsnapped: null, points: [[1, 1]], scale: 120, theme: "light", selected: null, curTransition: null, minorLines: true, + snap: false, rendering: { dirty: true, gridDirty: true, @@ -356,6 +359,8 @@ function dragStart(loc) { selected = id; } state.selected = selected; // if nothing selected this will null-ify it + state.ihatUnsnapped = state.ihat; + state.jhatUnsnapped = state.jhat; stateUpdated(); return selected !== null; } @@ -369,8 +374,16 @@ function dragContinue(delta) { state.points[idx][0] += move[0]; state.points[idx][1] += move[1]; } else { - state[state.selected][0] += delta[0] / state.scale; - state[state.selected][1] += delta[1] / state.scale; + if (state.snap) { + state[state.selected + "Unsnapped"][0] += delta[0] / state.scale; + state[state.selected + "Unsnapped"][1] += delta[1] / state.scale; + const snapScale = state.minorLines ? 2 : 1; + state.ihat = state.ihatUnsnapped.map(x => Math.round(x * snapScale) / snapScale); + state.jhat = state.jhatUnsnapped.map(x => Math.round(x * snapScale) / snapScale); + } else { + state[state.selected][0] += delta[0] / state.scale; + state[state.selected][1] += delta[1] / state.scale; + } } stateUpdated(); } @@ -378,6 +391,8 @@ function dragContinue(delta) { function dragEnd() { state.selected = null; + state.ihatUnsnapped = null; + state.jhatUnsnapped = null; stateUpdated(); } @@ -410,13 +425,19 @@ const ACTIONS = [ name: "swap", actionType: "move", action: () => ({ ihat: state.jhat, jhat: state.ihat }), - keys: ["KeyS"] + keys: ["alt", "KeyS"] }, { name: "minorLines", actionType: "toggle", stateBool: "minorLines", keys: ["KeyM"] + }, + { + name: "snap", + actionType: "toggle", + stateBool: "snap", + keys: ["KeyS"] } ]; @@ -524,7 +545,21 @@ document.addEventListener("DOMContentLoaded", () => { const btn = document.getElementById("action-" + action.name); action.keys.forEach(key => { document.body.addEventListener("keydown", e => { - if (!e.ctrlKey && !e.altKey && !e.metaKey && (state.curTransition === null) && (e.code === key)) execAction(id, e.shiftKey); + const mainKey = action.keys[action.keys.length - 1]; + if (e.code !== mainKey) return; + + // if we require a control key, make sure it's pressed + if (!e.ctrlKey && action.keys.includes("ctrl")) return; + if (!e.altKey && action.keys.includes("alt")) return; + if (!e.metaKey && action.keys.includes("meta")) return; + + // if a control key is pressed but we don't expect it, ignore + if (e.ctrlKey && !action.keys.includes("ctrl")) return; + if (e.altKey && !action.keys.includes("alt")) return; + if (e.metaKey && !action.keys.includes("meta")) return; + + if (state.curTransition !== null) return; + execAction(id, e.shiftKey); }); }); if (btn) { -- 2.45.2