rotation working, broke scale
Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
parent
dbcd588e29
commit
2c9eea4ce6
3 changed files with 267 additions and 116 deletions
|
@ -353,7 +353,7 @@
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
|
|
||||||
<!-- Configuration -->
|
<!-- Configuration -->
|
||||||
<script src="js/config.js?v=8da6a43" type="text/javascript"></script>
|
<script src="js/config.js?v=f903401" type="text/javascript"></script>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<script src="js/prompt.js?v=7a1c68c" type="text/javascript"></script>
|
<script src="js/prompt.js?v=7a1c68c" type="text/javascript"></script>
|
||||||
|
@ -379,7 +379,7 @@
|
||||||
src="js/ui/tool/colorbrush.js?v=8acb4f6"
|
src="js/ui/tool/colorbrush.js?v=8acb4f6"
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script
|
<script
|
||||||
src="js/ui/tool/select.js?v=ade791e"
|
src="js/ui/tool/select.js?v=3a96068"
|
||||||
type="text/javascript"></script>
|
type="text/javascript"></script>
|
||||||
<script src="js/ui/tool/stamp.js?v=3c07ac8" type="text/javascript"></script>
|
<script src="js/ui/tool/stamp.js?v=3c07ac8" type="text/javascript"></script>
|
||||||
<script
|
<script
|
||||||
|
|
10
js/config.js
10
js/config.js
|
@ -8,6 +8,16 @@ const config = makeReadOnly(
|
||||||
// Scroll Tick Limit (How much must scroll to reach next tick)
|
// Scroll Tick Limit (How much must scroll to reach next tick)
|
||||||
wheelTickSize: 50,
|
wheelTickSize: 50,
|
||||||
|
|
||||||
|
/** Select Tool */
|
||||||
|
// Handle Draw Size
|
||||||
|
handleDrawSize: 12,
|
||||||
|
// Handle Draw Hover Scale
|
||||||
|
handleDrawHoverScale: 1.3,
|
||||||
|
// Handle Detect Size
|
||||||
|
handleDetectSize: 20,
|
||||||
|
// Rotate Handle Distance (from selection)
|
||||||
|
rotateHandleDistance: 32,
|
||||||
|
|
||||||
// Endpoint
|
// Endpoint
|
||||||
api: makeReadOnly({path: "/sdapi/v1/"}),
|
api: makeReadOnly({path: "/sdapi/v1/"}),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* TODO: REFACTOR THIS WHOLE THING
|
||||||
|
*/
|
||||||
|
|
||||||
const selectTransformTool = () =>
|
const selectTransformTool = () =>
|
||||||
toolbar.registerTool(
|
toolbar.registerTool(
|
||||||
"./res/icons/box-select.svg",
|
"./res/icons/box-select.svg",
|
||||||
|
@ -70,6 +74,7 @@ const selectTransformTool = () =>
|
||||||
|
|
||||||
state.original = null;
|
state.original = null;
|
||||||
state.dragging = null;
|
state.dragging = null;
|
||||||
|
state.rotation = 0;
|
||||||
state._selected = null;
|
state._selected = null;
|
||||||
Object.defineProperty(state, "selected", {
|
Object.defineProperty(state, "selected", {
|
||||||
get: () => state._selected,
|
get: () => state._selected,
|
||||||
|
@ -114,6 +119,9 @@ const selectTransformTool = () =>
|
||||||
if (state.dragging) state.dragging = null;
|
if (state.dragging) state.dragging = null;
|
||||||
else state.selected = null;
|
else state.selected = null;
|
||||||
|
|
||||||
|
state.rotation = 0;
|
||||||
|
state.original = null;
|
||||||
|
|
||||||
state.redraw();
|
state.redraw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,56 +156,49 @@ const selectTransformTool = () =>
|
||||||
y <= this.y + this.h
|
y <= this.y + this.h
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
handles() {
|
center() {
|
||||||
const _createHandle = (x, y, originOffset = null) => {
|
return {x: this.x + this.w / 2, y: this.y + this.h / 2};
|
||||||
return {
|
},
|
||||||
x,
|
createHandle(x, y, originOffset = null) {
|
||||||
y,
|
return {
|
||||||
scaleTo: (tx, ty, keepAspectRatio = true) => {
|
x,
|
||||||
const origin = {
|
y,
|
||||||
x: this.original.x + this.original.w / 2,
|
scaleTo: (tx, ty, keepAspectRatio = true) => {
|
||||||
y: this.original.y + this.original.h / 2,
|
const origin = {
|
||||||
};
|
x: this.original.x + this.original.w / 2,
|
||||||
let nx = tx;
|
y: this.original.y + this.original.h / 2,
|
||||||
let ny = ty;
|
};
|
||||||
|
let nx = tx;
|
||||||
|
let ny = ty;
|
||||||
|
|
||||||
let xRatio = (nx - origin.x) / (x - origin.x);
|
let xRatio = (nx - origin.x) / (x - origin.x);
|
||||||
let yRatio = (ny - origin.y) / (y - origin.y);
|
let yRatio = (ny - origin.y) / (y - origin.y);
|
||||||
if (keepAspectRatio)
|
if (keepAspectRatio)
|
||||||
xRatio = yRatio = Math.min(xRatio, yRatio);
|
xRatio = yRatio = Math.min(xRatio, yRatio);
|
||||||
|
|
||||||
if (Number.isFinite(xRatio)) {
|
if (Number.isFinite(xRatio)) {
|
||||||
let left = this.original.x;
|
let left = this.original.x;
|
||||||
let right = this.original.x + this.original.w;
|
let right = this.original.x + this.original.w;
|
||||||
|
|
||||||
left = (left - origin.x) * xRatio + origin.x;
|
left = (left - origin.x) * xRatio + origin.x;
|
||||||
right = (right - origin.x) * xRatio + origin.x;
|
right = (right - origin.x) * xRatio + origin.x;
|
||||||
|
|
||||||
this.x = left;
|
this.x = left;
|
||||||
this.w = right - left;
|
this.w = right - left;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Number.isFinite(yRatio)) {
|
if (Number.isFinite(yRatio)) {
|
||||||
let top = this.original.y;
|
let top = this.original.y;
|
||||||
let bottom = this.original.y + this.original.h;
|
let bottom = this.original.y + this.original.h;
|
||||||
|
|
||||||
top = (top - origin.y) * yRatio + origin.y;
|
top = (top - origin.y) * yRatio + origin.y;
|
||||||
bottom = (bottom - origin.y) * yRatio + origin.y;
|
bottom = (bottom - origin.y) * yRatio + origin.y;
|
||||||
|
|
||||||
this.y = top;
|
this.y = top;
|
||||||
this.h = bottom - top;
|
this.h = bottom - top;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const size = viewport.zoom * 10;
|
|
||||||
return [
|
|
||||||
_createHandle(this.x, this.y, size),
|
|
||||||
_createHandle(this.x + this.w, this.y, size),
|
|
||||||
_createHandle(this.x, this.y + this.h, size),
|
|
||||||
_createHandle(this.x + this.w, this.y + this.h, size),
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -217,8 +218,6 @@ const selectTransformTool = () =>
|
||||||
y += snap(evn.y, 0, 64);
|
y += snap(evn.y, 0, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vpc = viewport.canvasToView(x, y);
|
|
||||||
|
|
||||||
uiCtx.save();
|
uiCtx.save();
|
||||||
|
|
||||||
// Update scale
|
// Update scale
|
||||||
|
@ -226,6 +225,12 @@ const selectTransformTool = () =>
|
||||||
state.scaling.scaleTo(x, y, state.keepAspectRatio);
|
state.scaling.scaleTo(x, y, state.keepAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update rotation
|
||||||
|
if (state.rotating) {
|
||||||
|
const center = state.selected.center();
|
||||||
|
state.rotation = Math.atan2(evn.x - center.x, center.y - evn.y);
|
||||||
|
}
|
||||||
|
|
||||||
// Update position
|
// Update position
|
||||||
if (state.moving) {
|
if (state.moving) {
|
||||||
state.selected.x = Math.round(x - state.moving.offset.x);
|
state.selected.x = Math.round(x - state.moving.offset.x);
|
||||||
|
@ -254,16 +259,17 @@ const selectTransformTool = () =>
|
||||||
uiCtx.setLineDash([]);
|
uiCtx.setLineDash([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw selected box
|
||||||
if (state.selected) {
|
if (state.selected) {
|
||||||
ovCtx.lineWidth = 1;
|
ovCtx.lineWidth = 1;
|
||||||
ovCtx.strokeStyle = "#FFF";
|
ovCtx.strokeStyle = "#FFF";
|
||||||
|
|
||||||
const bb = {
|
const bb = new BoundingBox({
|
||||||
x: state.selected.x,
|
x: state.selected.x,
|
||||||
y: state.selected.y,
|
y: state.selected.y,
|
||||||
w: state.selected.w,
|
w: state.selected.w,
|
||||||
h: state.selected.h,
|
h: state.selected.h,
|
||||||
};
|
});
|
||||||
|
|
||||||
const bbvp = {
|
const bbvp = {
|
||||||
...viewport.canvasToView(bb.x, bb.y),
|
...viewport.canvasToView(bb.x, bb.y),
|
||||||
|
@ -271,17 +277,32 @@ const selectTransformTool = () =>
|
||||||
h: viewport.zoom * bb.h,
|
h: viewport.zoom * bb.h,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const scenter = state.selected.center();
|
||||||
|
|
||||||
// Draw Image
|
// Draw Image
|
||||||
ovCtx.save();
|
ovCtx.save();
|
||||||
|
|
||||||
ovCtx.filter = `opacity(${state.selectionPeekOpacity}%)`;
|
ovCtx.filter = `opacity(${state.selectionPeekOpacity}%)`;
|
||||||
|
|
||||||
|
ovCtx.translate(scenter.x, scenter.y);
|
||||||
|
ovCtx.rotate(state.rotation);
|
||||||
|
|
||||||
|
const matrix = ovCtx.getTransform();
|
||||||
|
const imatrix = matrix.invertSelf();
|
||||||
|
|
||||||
|
const cursor = imatrix.transformPoint({
|
||||||
|
x: evn.x,
|
||||||
|
y: evn.y,
|
||||||
|
});
|
||||||
|
|
||||||
ovCtx.drawImage(
|
ovCtx.drawImage(
|
||||||
state.selected.image,
|
state.selected.image,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
state.selected.image.width,
|
state.selected.image.width,
|
||||||
state.selected.image.height,
|
state.selected.image.height,
|
||||||
state.selected.x,
|
-state.selected.w / 2,
|
||||||
state.selected.y,
|
-state.selected.h / 2,
|
||||||
state.selected.w,
|
state.selected.w,
|
||||||
state.selected.h
|
state.selected.h
|
||||||
);
|
);
|
||||||
|
@ -289,69 +310,122 @@ const selectTransformTool = () =>
|
||||||
|
|
||||||
state.originalDisplayLayer.clear();
|
state.originalDisplayLayer.clear();
|
||||||
state.originalDisplayLayer.ctx.save();
|
state.originalDisplayLayer.ctx.save();
|
||||||
|
|
||||||
|
state.originalDisplayLayer.ctx.translate(scenter.x, scenter.y);
|
||||||
|
state.originalDisplayLayer.ctx.rotate(state.rotation);
|
||||||
|
|
||||||
state.originalDisplayLayer.ctx.drawImage(
|
state.originalDisplayLayer.ctx.drawImage(
|
||||||
state.selected.image,
|
state.selected.image,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
state.selected.image.width,
|
state.selected.image.width,
|
||||||
state.selected.image.height,
|
state.selected.image.height,
|
||||||
state.selected.x,
|
-state.selected.w / 2,
|
||||||
state.selected.y,
|
-state.selected.h / 2,
|
||||||
state.selected.w,
|
state.selected.w,
|
||||||
state.selected.h
|
state.selected.h
|
||||||
);
|
);
|
||||||
state.originalDisplayLayer.ctx.restore();
|
state.originalDisplayLayer.ctx.restore();
|
||||||
|
|
||||||
|
uiCtx.save();
|
||||||
|
const centerx = bbvp.x + bbvp.w / 2;
|
||||||
|
const centery = bbvp.y + bbvp.h / 2;
|
||||||
|
|
||||||
|
uiCtx.translate(centerx, centery);
|
||||||
|
uiCtx.rotate(state.rotation);
|
||||||
|
|
||||||
|
const matrixvp = uiCtx.getTransform();
|
||||||
|
const imatrixvp = matrixvp.invertSelf();
|
||||||
|
|
||||||
|
const cursorvp = imatrixvp.transformPoint({
|
||||||
|
x: evn.evn.clientX,
|
||||||
|
y: evn.evn.clientY,
|
||||||
|
});
|
||||||
|
|
||||||
// Draw selection box
|
// Draw selection box
|
||||||
uiCtx.strokeStyle = "#FFF";
|
uiCtx.strokeStyle = "#FFF";
|
||||||
uiCtx.setLineDash([4, 2]);
|
uiCtx.setLineDash([4, 2]);
|
||||||
uiCtx.strokeRect(bbvp.x, bbvp.y, bbvp.w, bbvp.h);
|
uiCtx.strokeRect(-bbvp.w / 2, -bbvp.h / 2, bbvp.w, bbvp.h);
|
||||||
uiCtx.setLineDash([]);
|
uiCtx.setLineDash([]);
|
||||||
|
|
||||||
// Draw Scaling/Rotation Origin
|
// Draw Scaling/Rotation Origin
|
||||||
uiCtx.beginPath();
|
uiCtx.beginPath();
|
||||||
uiCtx.arc(
|
uiCtx.arc(0, 0, 5, 0, 2 * Math.PI);
|
||||||
bbvp.x + bbvp.w / 2,
|
|
||||||
bbvp.y + bbvp.h / 2,
|
|
||||||
5,
|
|
||||||
0,
|
|
||||||
2 * Math.PI
|
|
||||||
);
|
|
||||||
uiCtx.stroke();
|
uiCtx.stroke();
|
||||||
|
|
||||||
// Draw Scaling Handles
|
// Draw Rotation Handle
|
||||||
let cursorInHandle = false;
|
let cursorInAnyHandle = false;
|
||||||
state.selected.handles().forEach((handle) => {
|
{
|
||||||
const bbvph = {
|
let radius = config.handleDrawSize / 2;
|
||||||
...viewport.canvasToView(handle.x, handle.y),
|
|
||||||
w: 10,
|
|
||||||
h: 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
bbvph.x -= 5;
|
const dx = cursorvp.x;
|
||||||
bbvph.y -= 5;
|
const dy =
|
||||||
|
cursorvp.y - (-bbvp.h / 2 - config.rotateHandleDistance);
|
||||||
|
const dmax = config.handleDetectSize / 2;
|
||||||
|
|
||||||
const inhandle =
|
if (dx * dx + dy * dy < dmax * dmax) {
|
||||||
evn.evn.clientX > bbvph.x &&
|
cursorInAnyHandle ||= true;
|
||||||
evn.evn.clientX < bbvph.x + bbvph.w &&
|
radius *= config.handleDrawHoverScale;
|
||||||
evn.evn.clientY > bbvph.y &&
|
|
||||||
evn.evn.clientY < bbvph.y + bbvph.h;
|
|
||||||
|
|
||||||
if (inhandle) {
|
|
||||||
cursorInHandle = true;
|
|
||||||
uiCtx.strokeRect(
|
|
||||||
bbvph.x - 1,
|
|
||||||
bbvph.y - 1,
|
|
||||||
bbvph.w + 2,
|
|
||||||
bbvph.h + 2
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
uiCtx.strokeRect(bbvph.x, bbvph.y, bbvph.w, bbvph.h);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
uiCtx.beginPath();
|
||||||
|
uiCtx.moveTo(0, -bbvp.h / 2);
|
||||||
|
uiCtx.lineTo(
|
||||||
|
0,
|
||||||
|
-bbvp.h / 2 - config.rotateHandleDistance + radius
|
||||||
|
);
|
||||||
|
uiCtx.stroke();
|
||||||
|
|
||||||
|
uiCtx.beginPath();
|
||||||
|
uiCtx.arc(
|
||||||
|
0,
|
||||||
|
-bbvp.h / 2 - config.rotateHandleDistance,
|
||||||
|
radius,
|
||||||
|
0,
|
||||||
|
Math.PI * 2
|
||||||
|
);
|
||||||
|
uiCtx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw Scaling Handles
|
||||||
|
const drawHandle = (hx, hy) => {
|
||||||
|
// Handle Draw Range
|
||||||
|
let hs = config.handleDrawSize;
|
||||||
|
|
||||||
|
// Handle Detection Range
|
||||||
|
let dhs = config.handleDetectSize;
|
||||||
|
|
||||||
|
const handleBB = new BoundingBox({
|
||||||
|
x: hx - dhs / 2,
|
||||||
|
y: hy - dhs / 2,
|
||||||
|
w: dhs,
|
||||||
|
h: dhs,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cursorInHandle = handleBB.contains(cursorvp.x, cursorvp.y);
|
||||||
|
|
||||||
|
cursorInAnyHandle ||= cursorInHandle;
|
||||||
|
|
||||||
|
if (cursorInHandle) hs *= config.handleDrawHoverScale;
|
||||||
|
|
||||||
|
uiCtx.strokeRect(hx - hs / 2, hy - hs / 2, hs, hs);
|
||||||
|
};
|
||||||
|
|
||||||
|
drawHandle(-bbvp.w / 2, -bbvp.h / 2);
|
||||||
|
drawHandle(bbvp.w / 2, -bbvp.h / 2);
|
||||||
|
drawHandle(-bbvp.w / 2, bbvp.h / 2);
|
||||||
|
drawHandle(bbvp.w / 2, bbvp.h / 2);
|
||||||
|
|
||||||
|
uiCtx.restore();
|
||||||
|
|
||||||
// Change cursor
|
// Change cursor
|
||||||
if (cursorInHandle || state.selected.contains(evn.x, evn.y))
|
if (
|
||||||
|
cursorInAnyHandle ||
|
||||||
|
(-bb.w / 2 < cursor.x &&
|
||||||
|
bb.w / 2 > cursor.x &&
|
||||||
|
-bb.h / 2 < cursor.y &&
|
||||||
|
bb.h / 2 > cursor.y)
|
||||||
|
)
|
||||||
imageCollection.inputElement.style.cursor = "pointer";
|
imageCollection.inputElement.style.cursor = "pointer";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +443,8 @@ const selectTransformTool = () =>
|
||||||
state.original.x === state.selected.x &&
|
state.original.x === state.selected.x &&
|
||||||
state.original.y === state.selected.y &&
|
state.original.y === state.selected.y &&
|
||||||
state.original.w === state.selected.w &&
|
state.original.w === state.selected.w &&
|
||||||
state.original.h === state.selected.h)
|
state.original.h === state.selected.h &&
|
||||||
|
state.rotation === 0)
|
||||||
) {
|
) {
|
||||||
state.reset();
|
state.reset();
|
||||||
return;
|
return;
|
||||||
|
@ -386,12 +461,13 @@ const selectTransformTool = () =>
|
||||||
...state.original,
|
...state.original,
|
||||||
ctx: state.originalLayer.ctx,
|
ctx: state.originalLayer.ctx,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Use display layer as source
|
||||||
|
const {canvas, bb} = cropCanvas(state.originalDisplayLayer.canvas);
|
||||||
|
|
||||||
commands.runCommand("drawImage", "Image Transform Draw", {
|
commands.runCommand("drawImage", "Image Transform Draw", {
|
||||||
image: state.selected.image,
|
image: canvas,
|
||||||
x: Math.round(state.selected.x),
|
...bb,
|
||||||
y: Math.round(state.selected.y),
|
|
||||||
w: Math.round(state.selected.w),
|
|
||||||
h: Math.round(state.selected.h),
|
|
||||||
});
|
});
|
||||||
state.reset(true);
|
state.reset(true);
|
||||||
}
|
}
|
||||||
|
@ -408,35 +484,96 @@ const selectTransformTool = () =>
|
||||||
|
|
||||||
// If is selected, check if drag is in handles/body and act accordingly
|
// If is selected, check if drag is in handles/body and act accordingly
|
||||||
if (state.selected) {
|
if (state.selected) {
|
||||||
const handles = state.selected.handles();
|
// Get transformation matrices
|
||||||
|
const bb = {
|
||||||
|
x: state.selected.x,
|
||||||
|
y: state.selected.y,
|
||||||
|
w: state.selected.w,
|
||||||
|
h: state.selected.h,
|
||||||
|
};
|
||||||
|
|
||||||
const activeHandle = handles.find((v) => {
|
const bbvp = {
|
||||||
const vpc = viewport.canvasToView(v.x, v.y);
|
...viewport.canvasToView(bb.x, bb.y),
|
||||||
const tlc = viewport.viewToCanvas(vpc.x - 5, vpc.y - 5);
|
w: viewport.zoom * bb.w,
|
||||||
const brc = viewport.viewToCanvas(vpc.x + 5, vpc.y + 5);
|
h: viewport.zoom * bb.h,
|
||||||
const bb = {
|
};
|
||||||
x: tlc.x,
|
|
||||||
y: tlc.y,
|
const ivp = viewport.canvasToView(evn.ix, evn.iy);
|
||||||
w: brc.x - tlc.x,
|
|
||||||
h: brc.y - tlc.y,
|
// Viewport Coordinates
|
||||||
};
|
uiCtx.save();
|
||||||
|
const centerx = bbvp.x + bbvp.w / 2;
|
||||||
|
const centery = bbvp.y + bbvp.h / 2;
|
||||||
|
|
||||||
|
uiCtx.translate(centerx, centery);
|
||||||
|
uiCtx.rotate(state.rotation);
|
||||||
|
|
||||||
|
const matrixvp = uiCtx.getTransform();
|
||||||
|
const imatrixvp = matrixvp.invertSelf();
|
||||||
|
|
||||||
|
const cursorvp = imatrixvp.transformPoint(ivp);
|
||||||
|
|
||||||
|
uiCtx.restore();
|
||||||
|
|
||||||
|
// World Coordinates
|
||||||
|
const scenter = state.selected.center();
|
||||||
|
|
||||||
|
ovCtx.save();
|
||||||
|
|
||||||
|
ovCtx.translate(scenter.x, scenter.y);
|
||||||
|
ovCtx.rotate(state.rotation);
|
||||||
|
|
||||||
|
const matrix = ovCtx.getTransform();
|
||||||
|
const imatrix = matrix.invertSelf();
|
||||||
|
|
||||||
|
ovCtx.restore();
|
||||||
|
|
||||||
|
// Check rotation handle
|
||||||
|
let rotationHandle = false;
|
||||||
|
|
||||||
|
const dx = cursorvp.x;
|
||||||
|
const dy = cursorvp.y - (-bbvp.h / 2 - config.rotateHandleDistance);
|
||||||
|
const dmax = config.handleDetectSize / 2;
|
||||||
|
|
||||||
|
if (dx * dx + dy * dy < dmax * dmax) rotationHandle = true;
|
||||||
|
|
||||||
|
// Check handles
|
||||||
|
let activeHandle = null;
|
||||||
|
const testHandle = (hx, hy, hwx, hwy) => {
|
||||||
|
// Handle Detection Range
|
||||||
|
let dhs = config.handleDetectSize;
|
||||||
|
|
||||||
|
const handleBB = new BoundingBox({
|
||||||
|
x: hx - dhs / 2,
|
||||||
|
y: hy - dhs / 2,
|
||||||
|
w: dhs,
|
||||||
|
h: dhs,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (handleBB.contains(cursorvp.x, cursorvp.y)) {
|
||||||
|
activeHandle = state.selected.createHandle(hx, hy);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
testHandle(-bbvp.w / 2, -bbvp.h / 2);
|
||||||
|
testHandle(bbvp.w / 2, -bbvp.h / 2);
|
||||||
|
testHandle(-bbvp.w / 2, bbvp.h / 2);
|
||||||
|
testHandle(bbvp.w / 2, bbvp.h / 2);
|
||||||
|
|
||||||
return (
|
|
||||||
evn.ix > bb.x &&
|
|
||||||
evn.ix < bb.x + bb.w &&
|
|
||||||
evn.iy > bb.y &&
|
|
||||||
evn.iy < bb.y + bb.h
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if (activeHandle) {
|
if (activeHandle) {
|
||||||
state.scaling = activeHandle;
|
state.scaling = activeHandle;
|
||||||
return;
|
} else if (rotationHandle) {
|
||||||
} else if (state.selected.contains(ix, iy)) {
|
state.rotating = true;
|
||||||
|
} else if (state.selected.contains(evn.ix, evn.iy)) {
|
||||||
state.moving = {
|
state.moving = {
|
||||||
offset: {x: ix - state.selected.x, y: iy - state.selected.y},
|
snapOffset: {x: evn.ix - ix, y: evn.iy - iy},
|
||||||
|
offset: {
|
||||||
|
x: ix - state.selected.x,
|
||||||
|
y: iy - state.selected.y,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// If it is not, just create new selection
|
// If it is not, just create new selection
|
||||||
state.reset();
|
state.reset();
|
||||||
|
@ -457,6 +594,8 @@ const selectTransformTool = () =>
|
||||||
state.selected.updateOriginal();
|
state.selected.updateOriginal();
|
||||||
state.scaling = null;
|
state.scaling = null;
|
||||||
// If we are moving the selection, just... stop
|
// If we are moving the selection, just... stop
|
||||||
|
} else if (state.rotating) {
|
||||||
|
state.rotating = false;
|
||||||
} else if (state.moving) {
|
} else if (state.moving) {
|
||||||
state.moving = null;
|
state.moving = null;
|
||||||
/**
|
/**
|
||||||
|
@ -482,6 +621,8 @@ const selectTransformTool = () =>
|
||||||
category: "select-display",
|
category: "select-display",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
state.rotation = 0;
|
||||||
|
|
||||||
// Cut out selected portion of the image for manipulation
|
// Cut out selected portion of the image for manipulation
|
||||||
const cvs = document.createElement("canvas");
|
const cvs = document.createElement("canvas");
|
||||||
cvs.width = state.selected.w;
|
cvs.width = state.selected.w;
|
||||||
|
|
Loading…
Reference in a new issue