Merge pull request #84 from marcomarinodev/new-feature

Symmetry options
This commit is contained in:
Nicola 2022-02-05 22:55:56 +01:00 committed by GitHub
commit 4525479fa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 748 additions and 31 deletions

View File

@ -42,6 +42,16 @@
background: transparent;
}
#horizontal-symmetric {
z-index: 6001;
background: transparent;
}
#vertical-symmetric {
z-index: 6002;
background: transparent;
}
#tmp-canvas {
z-index: 5;
background: transparent;

View File

@ -11,6 +11,8 @@ class File {
VFXLayer = undefined;
TMPLayer = undefined;
pixelGrid = undefined;
hSymmetricLayer = undefined;
vSymmetricLayer = undefined;
checkerBoard = undefined
// Canvas resize attributes
@ -168,6 +170,8 @@ class File {
// Regenerate the checkerboard
currFile.checkerBoard.fillCheckerboard();
currFile.pixelGrid.fillPixelGrid();
currFile.hSymmetricLayer.fillAxis();
currFile.vSymmetricLayer.fillAxis();
// Put the imageDatas in the right position
switch (this.rcPivot)
{

View File

@ -23,7 +23,9 @@ const Settings = (() => {
enableEyedropperPreview: true, //unused - performance
numberOfHistoryStates: 256,
maxColorsOnImportedImage: 128,
pixelGridColour: '#000000'
pixelGridColour: '#000000',
hAxisGridColour: '#FF0000',
vAxisGridColour: '#0000FF',
};
}
else{
@ -44,8 +46,13 @@ const Settings = (() => {
//save new settings to settings object
settings.numberOfHistoryStates = Util.getValue('setting-numberOfHistoryStates');
settings.pixelGridColour = Util.getValue('setting-pixelGridColour');
settings.hAxisGridColour = Util.getValue('setting-hSymmetryColor');
settings.vAxisGridColour = Util.getValue('setting-vSymmetryColor');
// Filling pixel grid again if colour changed
Events.emit("refreshPixelGrid");
// Filling symmetric axes again if colour changed
Events.emit("refreshHorizontalAxis");
Events.emit("refreshVerticalAxis");
//save settings object to cookie
let cookieValue = JSON.stringify(settings);

View File

@ -86,6 +86,7 @@ const Startup = (() => {
Layer.unusedIDs.push(currentEntry.id);
// Removing the entry from the menu
currentEntry.remove();
}
}
@ -106,6 +107,12 @@ const Startup = (() => {
console.log("CREATED GRID");
currFile.pixelGrid = new PixelGrid(width, height, "pixel-grid");
// Horizontal symmetric layer
currFile.hSymmetricLayer = new HSymmetryLayer(width, height, "horizontal-symmetric");
// Vertical symmetric layer
currFile.vSymmetricLayer = new VSymmetryLayer(width, height, "vertical-symmetric");
// Creating the vfx layer on top of everything
currFile.VFXLayer = new Layer(width, height, 'vfx-canvas');
// Tmp layer to draw previews on
@ -116,6 +123,8 @@ const Startup = (() => {
currFile.layers.push(currFile.checkerBoard);
currFile.layers.push(currFile.currentLayer);
currFile.layers.push(currFile.TMPLayer);
currFile.layers.push(currFile.hSymmetricLayer);
currFile.layers.push(currFile.vSymmetricLayer);
currFile.layers.push(currFile.pixelGrid);
currFile.layers.push(currFile.VFXLayer);
}

View File

@ -0,0 +1,91 @@
class HSymmetryLayer extends Layer {
// is hidden && enabled
isEnabled = false;
// Distance between one line and another in HTML pixels
lineDistance = 10;
constructor(width, height, canvas, menuEntry) {
super(width, height, canvas, menuEntry);
this.initialize();
Events.onCustom("refreshHorizontalAxis", this.fillAxis.bind(this));
}
initialize() {
super.initialize();
this.fillAxis();
}
// Enable or not
disableAxis() {
// get toggle h axis button
let toggleButton = document.getElementById("toggle-h-symmetry-button");
toggleButton.innerHTML = "Show Horizontal Symmetry";
this.isEnabled = false;
this.canvas.style.display = "none";
}
enableAxis() {
// get toggle h axis button
let toggleButton = document.getElementById("toggle-h-symmetry-button");
toggleButton.innerHTML = "Hide Horizontal Symmetry";
this.isEnabled = true;
this.canvas.style.display = "inline-block";
}
initPaint() {
this.lineDistance = 5;
this.fillAxis();
}
repaint(factor) {
this.lineDistance += factor;
this.fillAxis();
}
normalPaint() {
this.lineDistance = 10;
this.fillAxis();
}
/**
* Shows or hides axis depending on its current visibility
* (triggered by the show h symmetry button in the top menu)
*/
toggleHAxis() {
console.log("toggleHAxis");
if (this.isEnabled) {
this.disableAxis();
} else {
this.enableAxis();
}
}
/**
* It fills the canvas
*/
fillAxis() {
let originalSize = currFile.canvasSize;
this.canvas.width = originalSize[0] * Math.round(this.lineDistance);
this.canvas.height = originalSize[1] * Math.round(this.lineDistance);
this.context.strokeStyle = Settings.getCurrSettings().hAxisGridColour;
// Draw horizontal axis
this.drawHAxis();
if (!this.isEnabled) {
this.canvas.style.display = 'none';
}
}
drawHAxis() {
// Get middle y
let midY = Math.round(this.canvas.height / 2);
this.context.beginPath();
this.context.moveTo(0, midY);
this.context.lineTo(this.canvas.width, midY);
this.context.stroke();
this.context.closePath();
}
}

View File

@ -52,7 +52,7 @@ class PixelGrid extends Layer {
this.fillPixelGrid();
}
/** Shows or hides the pixel grid depening on its current visibility
/** Shows or hides the pixel grid depending on its current visibility
* (triggered by the show pixel grid button in the top menu)
*
*/

View File

@ -0,0 +1,91 @@
class VSymmetryLayer extends Layer {
// is hidden && enabled
isEnabled = false;
// Distance between one line and another in HTML pixels
lineDistance = 10;
constructor(width, height, canvas, menuEntry) {
super(width, height, canvas, menuEntry);
this.initialize();
Events.onCustom("refreshVerticalAxis", this.fillAxis.bind(this));
}
initialize() {
super.initialize();
this.fillAxis();
}
// Enable or not
disableAxis() {
// get toggle h axis button
let toggleButton = document.getElementById("toggle-v-symmetry-button");
toggleButton.innerHTML = "Show Vertical Axis";
this.isEnabled = false;
this.canvas.style.display = "none";
}
enableAxis() {
// get toggle h axis button
let toggleButton = document.getElementById("toggle-v-symmetry-button");
toggleButton.innerHTML = "Hide Vertical Axis";
this.isEnabled = true;
this.canvas.style.display = "inline-block";
this.initPaint();
}
initPaint() {
this.lineDistance = 5;
this.fillAxis();
}
repaint(factor) {
this.lineDistance += factor;
this.fillAxis();
}
normalPaint() {
this.lineDistance = 10;
this.fillAxis();
}
/**
* Shows or hides axis depending on its current visibility
* (triggered by the show h symmetry button in the top menu)
*/
toggleVAxis() {
console.log("toggleVAxis");
if (this.isEnabled) {
this.disableAxis();
} else {
this.enableAxis();
}
}
/**
* It fills the canvas
*/
fillAxis() {
let originalSize = currFile.canvasSize;
this.canvas.width = originalSize[0] * Math.round(this.lineDistance);
this.canvas.height = originalSize[1] * Math.round(this.lineDistance);
this.context.strokeStyle = Settings.getCurrSettings().vAxisGridColour;
// Draw horizontal axis
this.drawVAxis();
if (!this.isEnabled) {
this.canvas.style.display = 'none';
}
}
drawVAxis() {
// Get middle y
let midX = Math.round(this.canvas.width / 2);
this.context.beginPath();
this.context.moveTo(midX, 0);
this.context.lineTo(midX, this.canvas.height);
this.context.stroke();
this.context.closePath();
}
}

View File

@ -32,6 +32,8 @@
/** SPECIAL LAYERS **/
//=include layers/Checkerboard.js
//=include layers/PixelGrid.js
//=include layers/HSymmetryLayer.js
//=include layers/VSymmetryLayer.js
/** TOOLS **/
//=include tools/DrawingTool.js

View File

@ -42,18 +42,98 @@ class BrushTool extends ResizableTool {
return;
//draw line to current pixel
if (cursorTarget.className == 'drawingCanvas' || cursorTarget.className == 'drawingCanvas') {
currFile.currentLayer.drawLine(Math.floor(this.prevMousePos[0]/currFile.zoom),
currFile.currentLayer.drawLine(
Math.floor(this.prevMousePos[0]/currFile.zoom),
Math.floor(this.prevMousePos[1]/currFile.zoom),
Math.floor(this.currMousePos[0]/currFile.zoom),
Math.floor(this.currMousePos[1]/currFile.zoom),
this.currSize
);
let midX = (currFile.canvasSize[0] / 2);
let midY = (currFile.canvasSize[1] / 2);
let prevMousePosX = Math.floor(this.prevMousePos[0] / currFile.zoom);
let prevMousePosY = Math.floor(this.prevMousePos[1] / currFile.zoom);
let currMousePosX = Math.floor(this.currMousePos[0] / currFile.zoom);
let currMousePosY = Math.floor(this.currMousePos[1] / currFile.zoom);
let mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY;
if (currFile.hSymmetricLayer.isEnabled) {
// if the current mouse position is over the horizontal axis
if (currMousePosY <= midY) {
console.log("Drawing over the horizontal axis");
mirrorPrevY = Math.floor(midY + Math.abs(midY - prevMousePosY));
mirrorCurrentY = Math.floor(midY + Math.abs(midY - currMousePosY));
} else {
console.log("Drawing under the horizontal axis");
mirrorPrevY = Math.floor(midY - Math.abs(midY - prevMousePosY));
mirrorCurrentY = Math.floor(midY - Math.abs(midY - currMousePosY));
}
this.mirrorDraw(
Math.floor(this.prevMousePos[0] / currFile.zoom),
mirrorPrevY,
Math.floor(this.currMousePos[0] / currFile.zoom),
mirrorCurrentY,
true, false
);
}
if (currFile.vSymmetricLayer.isEnabled) {
// console.log("midX => " + midX);
// console.log("currMouseX => " + currMousePosX);
// if the current mouse position is over the horizontal axis
if (currMousePosX <= midX) {
mirrorPrevX = Math.floor(midX + Math.abs(midX - prevMousePosX));
mirrorCurrentX = Math.floor(midX + Math.abs(midX - currMousePosX));
} else {
mirrorPrevX = Math.floor(midX - Math.abs(midX - prevMousePosX));
mirrorCurrentX = Math.floor(midX - Math.abs(midX - currMousePosX));
}
this.mirrorDraw(
mirrorPrevX,
Math.floor(this.prevMousePos[1] / currFile.zoom),
mirrorCurrentX,
Math.floor(this.currMousePos[1] / currFile.zoom),
false, true
);
}
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
this.mirrorDraw(mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY, true, true);
}
}
currFile.currentLayer.updateLayerPreview();
}
onEnd(mousePos) {
mirrorDraw(prevX, prevY, currX, currY, isHorizontal, isVertical) {
let horizontalFactor = (isHorizontal) ? 1 : 0;
let verticalFactor = (isVertical) ? 1 : 0;
if (this.currSize % 2 === 0) {
currFile.currentLayer.drawLine(
prevX,
prevY,
currX,
currY,
this.currSize
);
} else {
currFile.currentLayer.drawLine(
prevX - verticalFactor,
prevY - horizontalFactor,
currX - verticalFactor,
currY - horizontalFactor,
this.currSize
);
}
}
onEnd(mousePos) {
super.onEnd(mousePos);
}

View File

@ -35,9 +35,87 @@ class EraserTool extends ResizableTool {
);
}
let midX = (currFile.canvasSize[0] / 2);
let midY = (currFile.canvasSize[1] / 2);
let prevMousePosX = Math.floor(this.prevMousePos[0] / currFile.zoom);
let prevMousePosY = Math.floor(this.prevMousePos[1] / currFile.zoom);
let currMousePosX = Math.floor(this.currMousePos[0] / currFile.zoom);
let currMousePosY = Math.floor(this.currMousePos[1] / currFile.zoom);
let mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY;
// If Horizontal Symmetry mode is activated
// draw specular
if (currFile.hSymmetricLayer.isEnabled) {
// if the current mouse position is over the horizontal axis
if (currMousePosY <= midY) {
mirrorPrevY = Math.floor(midY + Math.abs(midY - prevMousePosY));
mirrorCurrentY = Math.floor(midY + Math.abs(midY - currMousePosY));
} else {
mirrorPrevY = Math.floor(midY - Math.abs(midY - prevMousePosY));
mirrorCurrentY = Math.floor(midY - Math.abs(midY - currMousePosY));
}
this.mirrorErase(
Math.floor(this.prevMousePos[0] / currFile.zoom),
mirrorPrevY,
Math.floor(this.currMousePos[0] / currFile.zoom),
mirrorCurrentY,
true, false
);
}
if (currFile.vSymmetricLayer.isEnabled) {
// console.log("midX => " + midX);
// console.log("currMouseX => " + currMousePosX);
// if the current mouse position is over the horizontal axis
if (currMousePosX <= midX) {
mirrorPrevX = Math.floor(midX + Math.abs(midX - prevMousePosX));
mirrorCurrentX = Math.floor(midX + Math.abs(midX - currMousePosX));
} else {
mirrorPrevX = Math.floor(midX - Math.abs(midX - prevMousePosX));
mirrorCurrentX = Math.floor(midX - Math.abs(midX - currMousePosX));
}
this.mirrorErase(
mirrorPrevX,
Math.floor(this.prevMousePos[1] / currFile.zoom),
mirrorCurrentX,
Math.floor(this.currMousePos[1] / currFile.zoom),
false, true
);
}
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
// Based on current mouse position we can infer which quadrant is the remaining one
this.mirrorErase(mirrorPrevX, mirrorPrevY, mirrorCurrentX, mirrorCurrentY, true, true);
}
currFile.currentLayer.updateLayerPreview();
}
mirrorErase(prevX, prevY, currX, currY, isHorizontal, isVertical) {
let horizontalFactor = (isHorizontal) ? 1 : 0;
let verticalFactor = (isVertical) ? 1 : 0;
if (this.currSize % 2 === 0) {
currFile.currentLayer.drawLine(
prevX,
prevY,
currX,
currY,
this.currSize, true
);
} else {
currFile.currentLayer.drawLine(
prevX - verticalFactor,
prevY - horizontalFactor,
currX - verticalFactor,
currY - horizontalFactor,
this.currSize, true
);
}
}
onEnd(mousePos) {
super.onEnd(mousePos);
this.endMousePos = mousePos;

View File

@ -14,10 +14,45 @@ class FillTool extends DrawingTool {
onStart(mousePos, target) {
super.onStart(mousePos);
this.startMousePos[0] = Math.floor(mousePos[0]) + 0.5;
this.startMousePos[1] = Math.floor(mousePos[1]) + 0.5;
if (target.className != 'drawingCanvas')
return;
new HistoryState().EditCanvas();
FillTool.fill(mousePos);
let midX = (currFile.canvasSize[0] / 2);
let midY = (currFile.canvasSize[1] / 2);
let x0 = Math.floor(this.startMousePos[0]/currFile.zoom);
let y0 = Math.floor(this.startMousePos[1]/currFile.zoom);
let mirrorX, mirrorY;
if (currFile.hSymmetricLayer.isEnabled) {
if (y0 <= midY) {
mirrorY = Math.floor(midY + Math.abs(midY - y0));
} else {
mirrorY = Math.floor(midY - Math.abs(midY - y0));
}
let symmetryPos = [mousePos[0], mirrorY * currFile.zoom];
FillTool.fill(symmetryPos);
}
if (currFile.vSymmetricLayer.isEnabled) {
if (x0 <= midX) {
mirrorX = Math.floor(midX + Math.abs(midX - x0));
} else {
mirrorX = Math.floor(midX - Math.abs(midX - x0));
}
let symmetryPos = [mirrorX * currFile.zoom, mousePos[1]];
FillTool.fill(symmetryPos);
}
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
let symmetryPos = [mirrorX * currFile.zoom, mirrorY * currFile.zoom];
FillTool.fill(symmetryPos);
}
currFile.currentLayer.updateLayerPreview();
}

View File

@ -85,6 +85,47 @@ class LineTool extends ResizableTool {
while (true) {
context.fillRect(x0-Math.floor(this.currSize/2), y0-Math.floor(this.currSize/2), this.currSize, this.currSize);
// handle symmetry
let midY = (currFile.canvasSize[1] / 2);
let midX = (currFile.canvasSize[0] / 2);
let mirrorX, mirrorY;
if (currFile.hSymmetricLayer.isEnabled) {
if (y0 <= midY) {
mirrorY = Math.floor(midY + Math.abs(midY - y0));
} else {
mirrorY = Math.floor(midY - Math.abs(midY - y0));
}
mirrorY -= (this.currSize % 2 === 0) ? 0 : 1;
context.fillRect(
x0 - Math.floor(this.currSize/2),
mirrorY - Math.floor(this.currSize/2),
this.currSize, this.currSize
);
}
if (currFile.vSymmetricLayer.isEnabled) {
if (x0 <= midX) {
mirrorX = Math.floor(midX + Math.abs(midX - x0));
} else {
mirrorX = Math.floor(midX - Math.abs(midX - x0));
}
mirrorX -= (this.currSize % 2 === 0) ? 0 : 1;
context.fillRect(
mirrorX - Math.floor(this.currSize/2),
y0 - Math.floor(this.currSize/2),
this.currSize, this.currSize
);
}
if (currFile.hSymmetricLayer.isEnabled && currFile.vSymmetricLayer.isEnabled) {
context.fillRect(
mirrorX - Math.floor(this.currSize/2),
mirrorY - Math.floor(this.currSize/2),
this.currSize, this.currSize
);
}
//if we've reached the end goal, exit the loop
if ((x0==x1) && (y0==y1)) break;
var e2 = 2*err;

View File

@ -8,6 +8,11 @@ class RectangleTool extends ResizableTool {
switchFunction = null;
// startX, startY, endX, endY of mirrored rectangles
horizontalMirrorCoordinates = [];
verticalMirrorCoordinates = [];
fourthQuadrantCoordinates = [];
constructor(name, options, switchFunction) {
super(name, options);
@ -51,6 +56,10 @@ class RectangleTool extends ResizableTool {
this.startMousePos[0] = Math.floor(mousePos[0] / currFile.zoom) + 0.5;
this.startMousePos[1] = Math.floor(mousePos[1] / currFile.zoom) + 0.5;
this.drawRect(this.startMousePos[0], this.startMousePos[1],
this.startMousePos[0], this.startMousePos[1]
);
new HistoryState().EditCanvas();
}
@ -74,7 +83,150 @@ class RectangleTool extends ResizableTool {
let startRectX = this.startMousePos[0];
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);
}
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
);
}
}
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
);
}
}
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
);
}
}
this.clearCanvas(tmpContext);
}
/**
* It draws the mirror rectangle with adjustments. It also fills rectangle if needed
* @param endMirrorRectX
* @param startMirrorRectX
* @param endMirrorRectY
* @param startMirrorRectY
*/
handleMirrorRectDrawing(endMirrorRectX, startMirrorRectX, endMirrorRectY, startMirrorRectY) {
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
);
}
}
/** Updates the layer preview and clears the tmp canvas
* @param {*} tmpContext tmp canvas context
*/
clearCanvas(tmpContext) {
// 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) {
let tmp = endRectX;
endRectX = startRectX;
@ -87,31 +239,12 @@ class RectangleTool extends ResizableTool {
startRectY = tmp;
}
// Drawing the rect
startRectY -= 0.5;
endRectY -= 0.5;
endRectX -= 0.5;
startRectX -= 0.5;
// Setting the correct linewidth and colour
currFile.currentLayer.context.lineWidth = this.currSize;
// 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);
}
startRectY -= 0.5;
endRectX -= 0.5;
endRectY -= 0.5;
return {endRectX, startRectX, endRectY, startRectY};
}
onSelect() {
super.onSelect();
@ -143,10 +276,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]);
}
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.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
];
}
}
}

View File

@ -60,18 +60,28 @@ class ZoomTool extends Tool {
// Adjust pixel grid thickness
if (zoomed) {
if (currFile.zoom <= 7)
if (currFile.zoom <= 7) {
currFile.pixelGrid.disablePixelGrid();
currFile.hSymmetricLayer.repaint((currFile.zoom - prevZoom) * 1.8);
currFile.vSymmetricLayer.repaint((currFile.zoom - prevZoom) * 1.8);
}
else if (currFile.zoom >= 20 && mode == 'in') {
currFile.pixelGrid.enablePixelGrid();
currFile.pixelGrid.repaintPixelGrid((currFile.zoom - prevZoom) * 0.6);
currFile.hSymmetricLayer.normalPaint();
currFile.vSymmetricLayer.normalPaint();
}
else if (prevZoom >= 20 && mode == 'out') {
currFile.pixelGrid.enablePixelGrid();
currFile.pixelGrid.repaintPixelGrid((currFile.zoom - prevZoom) * 0.6);
currFile.hSymmetricLayer.normalPaint();
currFile.vSymmetricLayer.normalPaint();
}
else {
currFile.pixelGrid.enablePixelGrid();
currFile.hSymmetricLayer.normalPaint();
currFile.vSymmetricLayer.normalPaint();
}
}

View File

@ -5,5 +5,7 @@
<canvas id="pixel-canvas" class = "drawingCanvas"></canvas>
<canvas id="checkerboard" class = "drawingCanvas"></canvas>
<canvas id="pixel-grid" class = "drawingCanvas"></canvas>
<canvas id="horizontal-symmetric" class="drawingCanvas"></canvas>
<canvas id="vertical-symmetric" class="drawingCanvas"></canvas>
</div>
<div id="canvas-view-shadow"></div>

View File

@ -24,6 +24,8 @@
<button>View</button>
<ul>
<li><button id="toggle-pixelgrid-button" onclick="currFile.pixelGrid.togglePixelGrid()">Show pixel grid</button></li>
<li><button id="toggle-h-symmetry-button" onclick="currFile.hSymmetricLayer.toggleHAxis()">Show Horizontal Axis</button></li>
<li><button id="toggle-v-symmetry-button" onclick="currFile.vSymmetricLayer.toggleVAxis()">Show Vertical Axis</button></li>
</ul>
</li>
<li>

View File

@ -12,6 +12,16 @@
<div class = "settings-entry">
<label for="setting-pixelGridColour">Colour of the pixel grid</label><input id="setting-pixelGridColour" value = "#0000FF" autocomplete="off"/>
</div>
<h2>Horizontal Axis</h2>
<div class = "settings-entry">
<label for="setting-hSymmetryColor">Colour of the horizontal axis</label><input id="setting-hSymmetryColor" value = "#FF0000" autocomplete="off"/>
</div>
<h2>Vertical Axis</h2>
<div class = "settings-entry">
<label for="setting-vSymmetryColor">Colour of the vertical axis</label><input id="setting-vSymmetryColor" value = "#0000FF" autocomplete="off"/>
</div>
</div>
<p id="cookies-disabled-warning">Your browsers cookies are disabled, settings will be lost upon closing this page.</p>