From 6b739f0ea7b46d2c99e25ee744439cd628b1fe71 Mon Sep 17 00:00:00 2001 From: unsettledgames <47360416+unsettledgames@users.noreply.github.com> Date: Sun, 31 Oct 2021 12:49:38 +0100 Subject: [PATCH] Added back rectangle tool --- js/ToolManager.js | 11 ++- js/_rectangle.js | 141 ------------------------------------ js/_toolButtons.js | 30 -------- js/_tools.js | 3 + js/pixel-editor.js | 1 - js/tools/BrushTool.js | 1 - js/tools/RectagleTool.js | 153 +++++++++++++++++++++++++++++++++++++++ js/tools/_all.js | 8 -- 8 files changed, 161 insertions(+), 187 deletions(-) delete mode 100644 js/_rectangle.js diff --git a/js/ToolManager.js b/js/ToolManager.js index 363a048..6e45435 100644 --- a/js/ToolManager.js +++ b/js/ToolManager.js @@ -1,6 +1,7 @@ const ToolManager = (() => { brush = new BrushTool("brush", {type: 'html'}, switchTool); eraser = new EraserTool("eraser", {type: 'html'}, switchTool); + rectangle = new RectangleTool("rectangle", {type: 'html'}, switchTool); currTool = brush; @@ -13,7 +14,7 @@ const ToolManager = (() => { return; let mousePos = Input.getCursorPosition(mouseEvent); - console.log("here"); + switch(mouseEvent.which) { case 1: if (!Input.isDragging()) { @@ -47,15 +48,15 @@ const ToolManager = (() => { let mousePos = Input.getCursorPosition(mouseEvent); switch(mouseEvent.which) { - case 0: + case 1: if (Input.isDragging()) { currTool.onEnd(mousePos); } break; - case 1: - break; case 2: break; + case 3: + break; default: break; } @@ -66,8 +67,6 @@ const ToolManager = (() => { } function switchTool(newTool) { - console.log("switch"); - currTool.onDeselect(); currTool = newTool; currTool.onSelect(); diff --git a/js/_rectangle.js b/js/_rectangle.js deleted file mode 100644 index 4c13e17..0000000 --- a/js/_rectangle.js +++ /dev/null @@ -1,141 +0,0 @@ -// RECT TOOL - -// Saving the empty rect svg -var emptyRectangleSVG = document.getElementById("rectangle-empty-button-svg"); -// and the full rect svg so that I can change them when the user changes rect modes -var fullRectangleSVG = document.getElementById("rectangle-full-button-svg"); - -// The start mode is empty rectangle -var rectangleDrawMode = 'empty'; -// I'm not drawing a rectangle at the beginning -var isDrawingRect = false; - -// Rect coordinates -let startRectX; -let startRectY; -let endRectX; -let endRectY; - -/** Starts drawing the rect, saves the start coordinates - * - * @param {*} mouseEvent - */ -function startRectDrawing(mouseEvent) { - // Putting the tmp layer on top of everything - TMPLayer.canvas.style.zIndex = parseInt(currentLayer.canvas.style.zIndex, 10) + 1; - // Updating flag - isDrawingRect = true; - - // Saving the start coords of the rect - let cursorPos = Input.getCursorPosition(mouseEvent); - startRectX = Math.floor(cursorPos[0] / zoom) + 0.5; - startRectY = Math.floor(cursorPos[1] / zoom) + 0.5; - - drawRectangle(startRectX, startRectY); -} - -/** Updates the rectangle preview depending on the position of the mouse - * - * @param {*} mouseEvent The mouseEvent from which we'll get the mouse position - */ -function updateRectDrawing(mouseEvent) { - let pos = Input.getCursorPosition(mouseEvent); - - // Drawing the rect at the right position - drawRectangle(Math.floor(pos[0] / zoom) + 0.5, Math.floor(pos[1] / zoom) + 0.5); -} - -/** Finishes drawing the rect, decides the end coordinates and moves the preview rectangle to the - * current layer - * - * @param {*} mouseEvent event from which we'll get the mouse position - */ -function endRectDrawing(mouseEvent) { - // Getting the end position - let currentPos = Input.getCursorPosition(mouseEvent); - let tmpContext = TMPLayer.context; - - endRectX = Math.floor(currentPos[0] / zoom) + 0.5; - endRectY = Math.floor(currentPos[1] / zoom) + 0.5; - - // Inverting end and start (start must always be the top left corner) - if (endRectX < startRectX) { - let tmp = endRectX; - endRectX = startRectX; - startRectX = tmp; - } - // Same for the y - if (endRectY < startRectY) { - let tmp = endRectY; - endRectY = startRectY; - startRectY = tmp; - } - - // Resetting this - isDrawingRect = false; - // Drawing the rect - startRectY -= 0.5; - endRectY -= 0.5; - endRectX -= 0.5; - startRectX -= 0.5; - - // Setting the correct linewidth and colour - currentLayer.context.lineWidth = tool.rectangle.brushSize; - - // Drawing the rect using 4 lines - line(startRectX, startRectY, endRectX, startRectY, tool.rectangle.brushSize); - line(endRectX, startRectY, endRectX, endRectY, tool.rectangle.brushSize); - line(endRectX, endRectY, startRectX, endRectY, tool.rectangle.brushSize); - line(startRectX, endRectY, startRectX, startRectY, tool.rectangle.brushSize); - - // If I have to fill it, I do so - if (rectangleDrawMode == 'fill') { - currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY); - } - - // Clearing the tmp canvas - tmpContext.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); -} - -/** Draws a rectangle with end coordinates given by x and y on the tmp layer (draws - * the preview for the rectangle tool) - * - * @param {*} x The current end x of the rectangle - * @param {*} y The current end y of the rectangle - */ -function drawRectangle(x, y) { - // Getting the tmp context - let tmpContext = TMPLayer.context; - - // Clearing the tmp canvas - tmpContext.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); - - // Drawing the rect - tmpContext.lineWidth = tool.rectangle.brushSize; - - // Drawing the rect - tmpContext.beginPath(); - if ((tool.rectangle.brushSize % 2 ) == 0) { - tmpContext.rect(startRectX - 0.5, startRectY - 0.5, x - startRectX, y - startRectY); - } - else { - tmpContext.rect(startRectX, startRectY, x - startRectX, y - startRectY); - } - - tmpContext.setLineDash([]); - tmpContext.stroke(); -} - -/** Sets the correct tool icon depending on its mode - * - */ -function setRectToolSvg() { - if (rectangleDrawMode == 'empty') { - emptyRectangleSVG.setAttribute('display', 'visible'); - fullRectangleSVG.setAttribute('display', 'none'); - } - else { - emptyRectangleSVG.setAttribute('display', 'none'); - fullRectangleSVG.setAttribute('display', 'visible'); - } -} \ No newline at end of file diff --git a/js/_toolButtons.js b/js/_toolButtons.js index 29aa412..01319e0 100644 --- a/js/_toolButtons.js +++ b/js/_toolButtons.js @@ -1,22 +1,3 @@ -// REFACTOR: add to single Tool implementations -// rectangle -Events.on('click','rectangle-button', function(e){ - // If the user clicks twice on the button, they change the draw mode - if (currentTool.name == 'rectangle') { - if (rectangleDrawMode == 'empty') { - rectangleDrawMode = 'fill'; - setRectToolSvg(); - } - else { - rectangleDrawMode = 'empty'; - setRectToolSvg(); - } - } - else { - tool.rectangle.switchTo(); - } -}, false); - // ellipse Events.on('click','ellipse-button', function(e){ // If the user clicks twice on the button, they change the draw mode @@ -35,17 +16,6 @@ Events.on('click','ellipse-button', function(e){ } }, false); -// rectangle bigger -Events.on('click',"rectangle-bigger-button", function(){ - tool.rectangle.brushSize++; -}, false); - -// rectangle smaller -Events.on('click',"rectangle-smaller-button", function(e){ - if(tool.rectangle.brushSize > 1) - tool.rectangle.brushSize--; -}, false); - // ellipse bigger Events.on('click',"ellipse-bigger-button", function(){ tool.ellipse.brushSize++; diff --git a/js/_tools.js b/js/_tools.js index bae800c..7bd52de 100644 --- a/js/_tools.js +++ b/js/_tools.js @@ -5,6 +5,7 @@ var tool = {}; //class for tools class Tool { name = "AbstractTool"; + isSelected = false; // Cursor and brush size cursorType = {}; @@ -35,6 +36,7 @@ class Tool { onSelect() { this.mainButton.parentElement.classList.add("selected"); + this.isSelected = true; /* //copy options to this object if (options.cursor) { @@ -87,6 +89,7 @@ class Tool { onDeselect() { this.mainButton.parentElement.classList.remove("selected"); + this.isSelected = false; } onStart(mousePos) { diff --git a/js/pixel-editor.js b/js/pixel-editor.js index 8120763..45f17d2 100644 --- a/js/pixel-editor.js +++ b/js/pixel-editor.js @@ -47,7 +47,6 @@ //=include TopMenuModule.js //=include _rectSelect.js //=include _move.js -//=include _rectangle.js //=include _ellipse.js /**event listeners**/ diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js index 175e898..8ca15ec 100644 --- a/js/tools/BrushTool.js +++ b/js/tools/BrushTool.js @@ -31,7 +31,6 @@ class BrushTool extends Tool { onEnd(mousePos) { super.onEnd(mousePos); - this.endMousePos = mousePos; } onSelect() { diff --git a/js/tools/RectagleTool.js b/js/tools/RectagleTool.js index e69de29..112e732 100644 --- a/js/tools/RectagleTool.js +++ b/js/tools/RectagleTool.js @@ -0,0 +1,153 @@ +class RectangleTool extends Tool { + // Saving the empty rect svg + emptyRectangleSVG = document.getElementById("rectangle-empty-button-svg"); + // and the full rect svg so that I can change them when the user changes rect modes + fullRectangleSVG = document.getElementById("rectangle-full-button-svg"); + // Current fill mode + currFillMode = 'empty'; + + switchFunction = null; + isDrawing = false; + + constructor(name, options, switchFunction) { + super(name, options); + + this.switchFunction = switchFunction; + Events.on('click', this.mainButton, this.changeFillType.bind(this)); + Events.on('click', this.biggerButton, this.increaseSize.bind(this)); + Events.on('click', this.smallerButton, this.decreaseSize.bind(this)); + } + + changeFillType() { + if (this.isSelected) + if (this.currFillMode == 'empty') { + this.currFillMode = 'full'; + this.emptyRectangleSVG.setAttribute('display', 'none'); + this.fullRectangleSVG.setAttribute('display', 'visible'); + } + else { + this.currFillMode = 'empty' + this.emptyRectangleSVG.setAttribute('display', 'visible'); + this.fullRectangleSVG.setAttribute('display', 'none'); + } + else + this.switchFunction(this); + } + + onStart(mousePos) { + super.onStart(mousePos); + + console.log("Rect start"); + + // Putting the tmp layer on top of everything + TMPLayer.canvas.style.zIndex = parseInt(currentLayer.canvas.style.zIndex, 10) + 1; + // Updating flag + this.isDrawing = true; + + this.startMousePos[0] = Math.floor(mousePos[0] / zoom) + 0.5; + this.startMousePos[1] = Math.floor(mousePos[1] / zoom) + 0.5; + } + + onDrag(mousePos, cursorTarget) { + super.onDrag(mousePos); + console.log("dragging"); + + // Drawing the rect at the right position + this.drawRect(Math.floor(mousePos[0] / zoom) + 0.5, Math.floor(mousePos[1] / zoom) + 0.5); + } + + /** Finishes drawing the rect, decides the end coordinates and moves the preview rectangle to the + * current layer + * + * @param {*} mousePos The position of the mouse when the user stopped dragging + */ + onEnd(mousePos) { + super.onEnd(mousePos); + console.log("Rect end"); + + let tmpContext = TMPLayer.context; + + let endRectX = Math.floor(mousePos[0] / zoom) + 0.5; + let endRectY = Math.floor(mousePos[1] / zoom) + 0.5; + let startRectX = this.startMousePos[0]; + let startRectY = this.startMousePos[1]; + + // Inverting end and start (start must always be the top left corner) + if (endRectX < startRectX) { + let tmp = endRectX; + endRectX = startRectX; + startRectX = tmp; + } + // Same for the y + if (endRectY < startRectY) { + let tmp = endRectY; + endRectY = startRectY; + startRectY = tmp; + } + + // Drawing the rect + startRectY -= 0.5; + endRectY -= 0.5; + endRectX -= 0.5; + startRectX -= 0.5; + + // Setting the correct linewidth and colour + currentLayer.context.lineWidth = this.currSize; + + // Drawing the rect using 4 lines + line(startRectX, startRectY, endRectX, startRectY, this.currSize); + line(endRectX, startRectY, endRectX, endRectY, this.currSize); + line(endRectX, endRectY, startRectX, endRectY, this.currSize); + line(startRectX, endRectY, startRectX, startRectY, this.currSize); + + // If I have to fill it, I do so + if (this.currFillMode == 'fill') { + currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY); + } + + // Update the layer preview + currentLayer.updateLayerPreview(); + // Clearing the tmp canvas + tmpContext.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); + // I finished drawing + this.isDrawing = false; + } + + onSelect() { + super.onSelect(); + } + + onDeselect() { + super.onDeselect(); + } + + /** Draws a rectangle with end coordinates given by x and y on the tmp layer (draws + * the preview for the rectangle tool) + * + * @param {*} x The current end x of the rectangle + * @param {*} y The current end y of the rectangle + */ + drawRect(x, y) { + console.log("here"); + // Getting the tmp context + let tmpContext = TMPLayer.context; + + // Clearing the tmp canvas + tmpContext.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height); + + // Drawing the rect + tmpContext.lineWidth = this.currSize; + + // Drawing the rect + tmpContext.beginPath(); + if ((this.currSize % 2 ) == 0) { + 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.setLineDash([]); + tmpContext.stroke(); + } +} \ No newline at end of file diff --git a/js/tools/_all.js b/js/tools/_all.js index acfcde9..db4c2f0 100644 --- a/js/tools/_all.js +++ b/js/tools/_all.js @@ -22,18 +22,10 @@ new Tool('pan', { }); -new Tool('rectangle', { - cursor: 'none', - brushPreview: true, -}); new Tool('ellipse', { cursor: 'none', brushPreview: true, }); -new Tool('resizerectangle', { - cursor: 'default', -}); - new Tool('rectselect', { cursor: 'crosshair', brushPreview: true,