feat: Selection mirroring
For now only horizontal flip (we can add vertical flip too, but it would be redundant) Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
parent
64bc673f45
commit
1dcb897839
2 changed files with 60 additions and 6 deletions
|
@ -488,7 +488,7 @@
|
||||||
src="js/ui/tool/colorbrush.js?v=84ff9fa"
|
src="js/ui/tool/colorbrush.js?v=84ff9fa"
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script
|
<script
|
||||||
src="js/ui/tool/select.js?v=044d8f3"
|
src="js/ui/tool/select.js?v=dfacef5"
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script src="js/ui/tool/stamp.js?v=4494df6" type="text/javascript"></script>
|
<script src="js/ui/tool/stamp.js?v=4494df6" type="text/javascript"></script>
|
||||||
<script
|
<script
|
||||||
|
|
|
@ -33,7 +33,9 @@ const selectTransformTool = () =>
|
||||||
keyboard.onShortcut({ctrl: true, key: "KeyC"}, state.ctrlccb);
|
keyboard.onShortcut({ctrl: true, key: "KeyC"}, state.ctrlccb);
|
||||||
keyboard.onShortcut({ctrl: true, key: "KeyV"}, state.ctrlvcb);
|
keyboard.onShortcut({ctrl: true, key: "KeyV"}, state.ctrlvcb);
|
||||||
keyboard.onShortcut({ctrl: true, key: "KeyX"}, state.ctrlxcb);
|
keyboard.onShortcut({ctrl: true, key: "KeyX"}, state.ctrlxcb);
|
||||||
|
keyboard.onShortcut({key: "Equal"}, state.togglemirror);
|
||||||
|
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox.disabled = true;
|
||||||
state.selected = null;
|
state.selected = null;
|
||||||
|
|
||||||
// Register Layer
|
// Register Layer
|
||||||
|
@ -59,6 +61,7 @@ const selectTransformTool = () =>
|
||||||
keyboard.deleteShortcut(state.ctrlccb, "KeyC");
|
keyboard.deleteShortcut(state.ctrlccb, "KeyC");
|
||||||
keyboard.deleteShortcut(state.ctrlvcb, "KeyV");
|
keyboard.deleteShortcut(state.ctrlvcb, "KeyV");
|
||||||
keyboard.deleteShortcut(state.ctrlxcb, "KeyX");
|
keyboard.deleteShortcut(state.ctrlxcb, "KeyX");
|
||||||
|
keyboard.deleteShortcut(state.togglemirror, "Equal");
|
||||||
|
|
||||||
uil.onactive.clear(state.uilayeractivecb);
|
uil.onactive.clear(state.uilayeractivecb);
|
||||||
|
|
||||||
|
@ -134,8 +137,12 @@ const selectTransformTool = () =>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.dragging) state.dragging = null;
|
if (state.dragging) state.dragging = null;
|
||||||
else state.selected = null;
|
else {
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox.disabled = true;
|
||||||
|
state.selected = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.mirrorSetValue(false);
|
||||||
state.rotation = 0;
|
state.rotation = 0;
|
||||||
state.original = null;
|
state.original = null;
|
||||||
moving = null;
|
moving = null;
|
||||||
|
@ -173,6 +180,11 @@ const selectTransformTool = () =>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Mirroring
|
||||||
|
state.togglemirror = () => {
|
||||||
|
state.mirrorSetValue(!state.mirrorSelection);
|
||||||
|
};
|
||||||
|
|
||||||
// Mouse Move Handler
|
// Mouse Move Handler
|
||||||
state.movecb = (evn) => {
|
state.movecb = (evn) => {
|
||||||
state.lastMouseMove = evn;
|
state.lastMouseMove = evn;
|
||||||
|
@ -247,6 +259,7 @@ const selectTransformTool = () =>
|
||||||
state.selected.scale.y === 1 &&
|
state.selected.scale.y === 1 &&
|
||||||
state.selected.position.x === state.original.sx &&
|
state.selected.position.x === state.original.sx &&
|
||||||
state.selected.position.y === state.original.sy &&
|
state.selected.position.y === state.original.sy &&
|
||||||
|
!state.mirrorSelection &&
|
||||||
state.original.layer === uil.layer
|
state.original.layer === uil.layer
|
||||||
) &&
|
) &&
|
||||||
!isCanvasBlank(
|
!isCanvasBlank(
|
||||||
|
@ -409,11 +422,17 @@ const selectTransformTool = () =>
|
||||||
const xs = lscursor.x / scaling.handle.x;
|
const xs = lscursor.x / scaling.handle.x;
|
||||||
const xy = lscursor.y / scaling.handle.y;
|
const xy = lscursor.y / scaling.handle.y;
|
||||||
|
|
||||||
if (!state.keepAspectRatio) state.selected.scale = {x: xs, y: xy};
|
let xscale = 1;
|
||||||
else {
|
let yscale = 1;
|
||||||
const scale = Math.max(xs, xy);
|
|
||||||
state.selected.scale = {x: scale, y: scale};
|
if (!state.keepAspectRatio) {
|
||||||
|
xscale = xs;
|
||||||
|
yscale = ys;
|
||||||
|
} else {
|
||||||
|
xscale = yscale = Math.max(xs, xy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.selected.scale = {x: xscale, y: yscale};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rotating) {
|
if (rotating) {
|
||||||
|
@ -460,6 +479,8 @@ const selectTransformTool = () =>
|
||||||
};
|
};
|
||||||
state.selected = new _tool.MarqueeSelection(canvas, bb.center);
|
state.selected = new _tool.MarqueeSelection(canvas, bb.center);
|
||||||
|
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox.disabled = false;
|
||||||
|
|
||||||
state.redraw();
|
state.redraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -511,6 +532,7 @@ const selectTransformTool = () =>
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox.disabled = true;
|
||||||
state.selected = null;
|
state.selected = null;
|
||||||
state.redraw();
|
state.redraw();
|
||||||
}
|
}
|
||||||
|
@ -668,6 +690,37 @@ const selectTransformTool = () =>
|
||||||
"icon-maximize"
|
"icon-maximize"
|
||||||
).checkbox;
|
).checkbox;
|
||||||
|
|
||||||
|
// Mirroring
|
||||||
|
state.onMirror = () => {
|
||||||
|
if (state.selected) {
|
||||||
|
const scale = state.selected.scale;
|
||||||
|
scale.x *= -1;
|
||||||
|
state.selected.scale = scale;
|
||||||
|
|
||||||
|
state.redraw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const {checkbox: mirrorCheckbox, setValue: _mirrorSetValue} =
|
||||||
|
_toolbar_input.checkbox(
|
||||||
|
state,
|
||||||
|
"openoutpaint/select-mirror",
|
||||||
|
"mirrorSelection",
|
||||||
|
"Mirror Selection",
|
||||||
|
"icon-flip-horizontal",
|
||||||
|
(v) => {
|
||||||
|
state.onMirror();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox = mirrorCheckbox;
|
||||||
|
state.ctxmenu.mirrorSelectionCheckbox.disabled = true;
|
||||||
|
_mirrorSetValue(false);
|
||||||
|
state.mirrorSetValue = (v) => {
|
||||||
|
_mirrorSetValue(v);
|
||||||
|
if (v !== state.mirrorSelection) {
|
||||||
|
state.onMirror();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Use Clipboard
|
// Use Clipboard
|
||||||
const clipboardCheckbox = _toolbar_input.checkbox(
|
const clipboardCheckbox = _toolbar_input.checkbox(
|
||||||
state,
|
state,
|
||||||
|
@ -817,6 +870,7 @@ const selectTransformTool = () =>
|
||||||
array.classList.add("checkbox-array");
|
array.classList.add("checkbox-array");
|
||||||
array.appendChild(state.ctxmenu.snapToGridLabel);
|
array.appendChild(state.ctxmenu.snapToGridLabel);
|
||||||
array.appendChild(state.ctxmenu.keepAspectRatioLabel);
|
array.appendChild(state.ctxmenu.keepAspectRatioLabel);
|
||||||
|
array.appendChild(state.ctxmenu.mirrorSelectionCheckbox);
|
||||||
array.appendChild(state.ctxmenu.useClipboardLabel);
|
array.appendChild(state.ctxmenu.useClipboardLabel);
|
||||||
menu.appendChild(array);
|
menu.appendChild(array);
|
||||||
menu.appendChild(state.ctxmenu.selectionPeekOpacitySlider);
|
menu.appendChild(state.ctxmenu.selectionPeekOpacitySlider);
|
||||||
|
|
Loading…
Reference in a new issue