mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
rectangle symmetry
This commit is contained in:
@@ -81,7 +81,6 @@ class BrushTool extends ResizableTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
|
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
|
||||||
// Based on current mouse position we can infer which quadrant is the remaining one
|
|
||||||
this.mirrorDraw(mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY, true, true);
|
this.mirrorDraw(mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,11 @@ class RectangleTool extends ResizableTool {
|
|||||||
|
|
||||||
switchFunction = null;
|
switchFunction = null;
|
||||||
|
|
||||||
|
// startX, startY, endX, endY of mirrored rectangles
|
||||||
|
horizontalMirrorCoordinates = [];
|
||||||
|
verticalMirrorCoordinates = [];
|
||||||
|
fourthQuadrantCoordinates = [];
|
||||||
|
|
||||||
constructor(name, options, switchFunction) {
|
constructor(name, options, switchFunction) {
|
||||||
super(name, options);
|
super(name, options);
|
||||||
|
|
||||||
@@ -67,7 +72,157 @@ class RectangleTool extends ResizableTool {
|
|||||||
let startRectX = this.startMousePos[0];
|
let startRectX = this.startMousePos[0];
|
||||||
let startRectY = this.startMousePos[1];
|
let startRectY = this.startMousePos[1];
|
||||||
|
|
||||||
// Inverting end and start (start must always be the top left corner)
|
const coordinates = this.adjustCoordinates(
|
||||||
|
endRectX,
|
||||||
|
startRectX,
|
||||||
|
endRectY,
|
||||||
|
startRectY
|
||||||
|
);
|
||||||
|
|
||||||
|
endRectX = coordinates.endRectX;
|
||||||
|
startRectX = coordinates.startRectX;
|
||||||
|
endRectY = coordinates.endRectY;
|
||||||
|
startRectY = coordinates.startRectY;
|
||||||
|
|
||||||
|
// Setting the correct linewidth and colour
|
||||||
|
currFile.currentLayer.context.lineWidth = this.currSize;
|
||||||
|
|
||||||
|
// Drawing the rect using 4 lines
|
||||||
|
this.drawFinalRect(startRectX, startRectY, endRectX, endRectY);
|
||||||
|
|
||||||
|
// If I have to fill it, I do so
|
||||||
|
if (this.currFillMode == 'fill') {
|
||||||
|
currFile.currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearCanvas(tmpContext);
|
||||||
|
|
||||||
|
if (currFile.hSymmetricLayer.isEnabled) {
|
||||||
|
if (typeof this.horizontalMirrorCoordinates != 'undefined') {
|
||||||
|
|
||||||
|
let startMirrorRectX = this.horizontalMirrorCoordinates[0];
|
||||||
|
let startMirrorRectY = this.horizontalMirrorCoordinates[1];
|
||||||
|
let endMirrorRectX = this.horizontalMirrorCoordinates[2];
|
||||||
|
let endMirrorRectY = this.horizontalMirrorCoordinates[3];
|
||||||
|
|
||||||
|
this.handleMirrorRectDrawing(
|
||||||
|
endMirrorRectX,
|
||||||
|
startMirrorRectX,
|
||||||
|
endMirrorRectY,
|
||||||
|
startMirrorRectY,
|
||||||
|
tmpContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currFile.vSymmetricLayer.isEnabled) {
|
||||||
|
if (typeof this.verticalMirrorCoordinates != 'undefined') {
|
||||||
|
|
||||||
|
let startMirrorRectX = this.verticalMirrorCoordinates[0];
|
||||||
|
let startMirrorRectY = this.verticalMirrorCoordinates[1];
|
||||||
|
let endMirrorRectX = this.verticalMirrorCoordinates[2];
|
||||||
|
let endMirrorRectY = this.verticalMirrorCoordinates[3];
|
||||||
|
|
||||||
|
this.handleMirrorRectDrawing(
|
||||||
|
endMirrorRectX,
|
||||||
|
startMirrorRectX,
|
||||||
|
endMirrorRectY,
|
||||||
|
startMirrorRectY,
|
||||||
|
tmpContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
|
||||||
|
if (typeof this.fourthQuadrantCoordinates != 'undefined') {
|
||||||
|
let startMirrorRectX = this.fourthQuadrantCoordinates[0];
|
||||||
|
let startMirrorRectY = this.fourthQuadrantCoordinates[1];
|
||||||
|
let endMirrorRectX = this.fourthQuadrantCoordinates[2];
|
||||||
|
let endMirrorRectY = this.fourthQuadrantCoordinates[3];
|
||||||
|
|
||||||
|
this.handleMirrorRectDrawing(
|
||||||
|
endMirrorRectX,
|
||||||
|
startMirrorRectX,
|
||||||
|
endMirrorRectY,
|
||||||
|
startMirrorRectY,
|
||||||
|
tmpContext
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It draws the mirror rectangle with adjustments. It also fills rectangle if needed
|
||||||
|
* @param endMirrorRectX
|
||||||
|
* @param startMirrorRectX
|
||||||
|
* @param endMirrorRectY
|
||||||
|
* @param startMirrorRectY
|
||||||
|
* @param tmpContext
|
||||||
|
*/
|
||||||
|
handleMirrorRectDrawing(endMirrorRectX, startMirrorRectX, endMirrorRectY, startMirrorRectY, tmpContext) {
|
||||||
|
const mirrorCoordinates = this.adjustCoordinates(
|
||||||
|
endMirrorRectX,
|
||||||
|
startMirrorRectX,
|
||||||
|
endMirrorRectY,
|
||||||
|
startMirrorRectY
|
||||||
|
);
|
||||||
|
|
||||||
|
endMirrorRectX = mirrorCoordinates.endRectX
|
||||||
|
startMirrorRectX = mirrorCoordinates.startRectX;
|
||||||
|
endMirrorRectY = mirrorCoordinates.endRectY
|
||||||
|
startMirrorRectY = mirrorCoordinates.startRectY;
|
||||||
|
|
||||||
|
// Setting the correct linewidth and colour
|
||||||
|
currFile.currentLayer.context.lineWidth = this.currSize;
|
||||||
|
|
||||||
|
this.drawFinalRect(startMirrorRectX, startMirrorRectY, endMirrorRectX, endMirrorRectY);
|
||||||
|
|
||||||
|
// If I have to fill it, I do so
|
||||||
|
if (this.currFillMode == 'fill') {
|
||||||
|
currFile.currentLayer.context.fillRect(
|
||||||
|
startMirrorRectX,
|
||||||
|
startMirrorRectY,
|
||||||
|
endMirrorRectX - startMirrorRectX,
|
||||||
|
endMirrorRectY - startMirrorRectY
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.clearCanvas(tmpContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates the layer preview and clears the tmp canvas
|
||||||
|
* @param {*} tmpContext tmp canvas context
|
||||||
|
*/
|
||||||
|
clearCanvas(tmpContext) {
|
||||||
|
// Update the layer preview
|
||||||
|
currFile.currentLayer.updateLayerPreview();
|
||||||
|
// Clearing the tmp canvas
|
||||||
|
tmpContext.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the final rectangle after preview (used in handleMirrorRectDrawing)
|
||||||
|
* @param startRectX
|
||||||
|
* @param startRectY
|
||||||
|
* @param endRectX
|
||||||
|
* @param endRectY
|
||||||
|
*/
|
||||||
|
drawFinalRect(startRectX, startRectY, endRectX, endRectY) {
|
||||||
|
currFile.currentLayer.drawLine(startRectX, startRectY, endRectX, startRectY, this.currSize);
|
||||||
|
currFile.currentLayer.drawLine(endRectX, startRectY, endRectX, endRectY, this.currSize);
|
||||||
|
currFile.currentLayer.drawLine(endRectX, endRectY, startRectX, endRectY, this.currSize);
|
||||||
|
currFile.currentLayer.drawLine(startRectX, endRectY, startRectX, startRectY, this.currSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rect coordinates adjustments before draw final rectangle (used in handleMirrorRectDrawing)
|
||||||
|
* @param endRectX
|
||||||
|
* @param startRectX
|
||||||
|
* @param endRectY
|
||||||
|
* @param startRectY
|
||||||
|
* @returns {{endRectY, endRectX, startRectY, startRectX}}
|
||||||
|
*/
|
||||||
|
adjustCoordinates(endRectX, startRectX, endRectY, startRectY) {
|
||||||
if (endRectX < startRectX) {
|
if (endRectX < startRectX) {
|
||||||
let tmp = endRectX;
|
let tmp = endRectX;
|
||||||
endRectX = startRectX;
|
endRectX = startRectX;
|
||||||
@@ -80,30 +235,11 @@ class RectangleTool extends ResizableTool {
|
|||||||
startRectY = tmp;
|
startRectY = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drawing the rect
|
|
||||||
startRectY -= 0.5;
|
|
||||||
endRectY -= 0.5;
|
|
||||||
endRectX -= 0.5;
|
|
||||||
startRectX -= 0.5;
|
startRectX -= 0.5;
|
||||||
|
startRectY -= 0.5;
|
||||||
// Setting the correct linewidth and colour
|
endRectX -= 0.5;
|
||||||
currFile.currentLayer.context.lineWidth = this.currSize;
|
endRectY -= 0.5;
|
||||||
|
return {endRectX, startRectX, endRectY, startRectY};
|
||||||
// Drawing the rect using 4 lines
|
|
||||||
currFile.currentLayer.drawLine(startRectX, startRectY, endRectX, startRectY, this.currSize);
|
|
||||||
currFile.currentLayer.drawLine(endRectX, startRectY, endRectX, endRectY, this.currSize);
|
|
||||||
currFile.currentLayer.drawLine(endRectX, endRectY, startRectX, endRectY, this.currSize);
|
|
||||||
currFile.currentLayer.drawLine(startRectX, endRectY, startRectX, startRectY, this.currSize);
|
|
||||||
|
|
||||||
// If I have to fill it, I do so
|
|
||||||
if (this.currFillMode == 'fill') {
|
|
||||||
currFile.currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the layer preview
|
|
||||||
currFile.currentLayer.updateLayerPreview();
|
|
||||||
// Clearing the tmp canvas
|
|
||||||
tmpContext.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelect() {
|
onSelect() {
|
||||||
@@ -136,10 +272,122 @@ class RectangleTool extends ResizableTool {
|
|||||||
tmpContext.rect(this.startMousePos[0] - 0.5, this.startMousePos[1] - 0.5, x - this.startMousePos[0], y - this.startMousePos[1]);
|
tmpContext.rect(this.startMousePos[0] - 0.5, this.startMousePos[1] - 0.5, x - this.startMousePos[0], y - this.startMousePos[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tmpContext.rect(this.startMousePos[0], this.startMousePos[1], x - this.startMousePos[0], y - this.startMousePos[1]);
|
tmpContext.rect(
|
||||||
|
this.startMousePos[0],
|
||||||
|
this.startMousePos[1],
|
||||||
|
x - this.startMousePos[0],
|
||||||
|
y - this.startMousePos[1]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpContext.setLineDash([]);
|
tmpContext.setLineDash([]);
|
||||||
tmpContext.stroke();
|
tmpContext.stroke();
|
||||||
|
|
||||||
|
let midX = currFile.canvasSize[0] / 2;
|
||||||
|
let midY = currFile.canvasSize[1] / 2;
|
||||||
|
let startYMirror, endYMirror;
|
||||||
|
let startXMirror, endXMirror;
|
||||||
|
|
||||||
|
// Handling horizontal symmetry
|
||||||
|
if (currFile.hSymmetricLayer.isEnabled) {
|
||||||
|
// check if start mouse position y is under the y axis
|
||||||
|
if (this.startMousePos[1] <= midY) {
|
||||||
|
// console.log("[RECT] => Drawing over the y axis");
|
||||||
|
startYMirror = midY + Math.abs(midY - this.startMousePos[1]);
|
||||||
|
endYMirror = midY + Math.abs(midY - y);
|
||||||
|
} else {
|
||||||
|
// console.log("[RECT] => Drawing under the y axis");
|
||||||
|
startYMirror = midY - Math.abs(midY - this.startMousePos[1]);
|
||||||
|
endYMirror = midY - Math.abs(midY - y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Every time that a mirror is changed we must update mirrors array
|
||||||
|
tmpContext.beginPath();
|
||||||
|
if ((this.currSize % 2 ) == 0) {
|
||||||
|
tmpContext.rect(this.startMousePos[0] - 0.5, startYMirror - 0.5, x - this.startMousePos[0], endYMirror - startYMirror);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmpContext.rect(
|
||||||
|
this.startMousePos[0],
|
||||||
|
startYMirror,
|
||||||
|
x - this.startMousePos[0],
|
||||||
|
endYMirror - startYMirror
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tmpContext.setLineDash([]);
|
||||||
|
tmpContext.stroke();
|
||||||
|
|
||||||
|
this.horizontalMirrorCoordinates = [
|
||||||
|
this.startMousePos[0], // start mirror rect x
|
||||||
|
startYMirror, // start mirror rect y
|
||||||
|
x, // end mirror rect x
|
||||||
|
endYMirror// end mirror rect y
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling vertical symmetry
|
||||||
|
if (currFile.vSymmetricLayer.isEnabled) {
|
||||||
|
if (this.startMousePos[0] <= midX) {
|
||||||
|
startXMirror = midX + Math.abs(midX - this.startMousePos[0]);
|
||||||
|
endXMirror = midX + Math.abs(midX - x);
|
||||||
|
} else {
|
||||||
|
startXMirror = midX - Math.abs(midX - this.startMousePos[0]);
|
||||||
|
endXMirror = midX - Math.abs(midX - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpContext.beginPath();
|
||||||
|
if ((this.currSize % 2 ) == 0) {
|
||||||
|
tmpContext.rect(startXMirror - 0.5,
|
||||||
|
this.startMousePos[1] - 0.5,
|
||||||
|
endXMirror - startXMirror,
|
||||||
|
y - this.startMousePos[1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmpContext.rect(
|
||||||
|
startXMirror,
|
||||||
|
this.startMousePos[1],
|
||||||
|
endXMirror - startXMirror,
|
||||||
|
y - this.startMousePos[1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tmpContext.setLineDash([]);
|
||||||
|
tmpContext.stroke();
|
||||||
|
|
||||||
|
this.verticalMirrorCoordinates = [
|
||||||
|
startXMirror, // start mirror rect x
|
||||||
|
this.startMousePos[1], // start mirror rect y
|
||||||
|
endXMirror, // end mirror rect x
|
||||||
|
y// end mirror rect y
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
|
||||||
|
tmpContext.beginPath();
|
||||||
|
if ((this.currSize % 2 ) == 0) {
|
||||||
|
tmpContext.rect(startXMirror - 0.5,
|
||||||
|
startYMirror - 0.5,
|
||||||
|
endXMirror - startXMirror,
|
||||||
|
endYMirror - startYMirror
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
tmpContext.rect(
|
||||||
|
startXMirror,
|
||||||
|
startYMirror,
|
||||||
|
endXMirror - startXMirror,
|
||||||
|
endYMirror - startYMirror
|
||||||
|
);
|
||||||
|
}
|
||||||
|
tmpContext.setLineDash([]);
|
||||||
|
tmpContext.stroke();
|
||||||
|
|
||||||
|
this.fourthQuadrantCoordinates = [
|
||||||
|
startXMirror,
|
||||||
|
startYMirror,
|
||||||
|
endXMirror,
|
||||||
|
endYMirror
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user