~smitop/eigen.fun

f2b9d000990758bdd9d221a2f408395d7041f77a — Smitty 3 years ago 5531de3
option to snap to grid
2 files changed, 45 insertions(+), 5 deletions(-)

M public/index.html
M public/script.js
M public/index.html => public/index.html +6 -1
@@ 204,13 204,18 @@
            <button class="action" id="action-swap">
                <span class="name">Swap</span>
                <span class="icon"></span>
                <span class="shortcut">S</span>
                <span class="shortcut">Alt-S</span>
            </button>
            <button class="action" id="action-minorLines">
                <span class="name">Minor lines</span>
                <span class="icon"></span>
                <span class="shortcut">M</span>
            </button>
            <button class="action" id="action-snap">
                <span class="name">Snap</span>
                <span class="icon"></span>
                <span class="shortcut">S</span>
            </button>
        </nav>
        <canvas id="transform-canvas"></canvas>
        <canvas id="grid-canvas"></canvas>

M public/script.js => public/script.js +39 -4
@@ 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) {