From 832f36992bda91a1a1a900c8728bfdf48b7de893 Mon Sep 17 00:00:00 2001 From: Nicola <47360416+unsettledgames@users.noreply.github.com> Date: Sat, 22 Jan 2022 16:02:10 +0100 Subject: [PATCH] Added ellipse tool setup --- css/_tools-menu.scss | 8 ++- js/FeatureToggles.js | 4 +- js/ToolManager.js | 1 + js/pixel-editor.js | 3 +- js/tools/EllipseTool.js | 143 +++++++++++++++++++++++++++++++++++++++ js/tools/_ellipse.js | 144 ---------------------------------------- svg/ellipse.svg | 11 +-- svg/filledellipse.svg | 28 ++------ views/tools-menu.hbs | 5 +- 9 files changed, 168 insertions(+), 179 deletions(-) create mode 100644 js/tools/EllipseTool.js delete mode 100644 js/tools/_ellipse.js diff --git a/css/_tools-menu.scss b/css/_tools-menu.scss index 894527e..704b041 100644 --- a/css/_tools-menu.scss +++ b/css/_tools-menu.scss @@ -28,12 +28,14 @@ z-index:0; } -#tools-menu li button path { +#tools-menu li button path, #tools-menu li button ellipse { fill: $baseicon; + stroke: $baseicon; } -#tools-menu li:hover button:first-child path { +#tools-menu li:hover button:first-child path, #tools-menu li:hover button:first-child ellipse { fill: $basehovericon; + stroke: $basehovericon; } @@ -41,7 +43,7 @@ background: $baseselected !important; } -#tools-menu li.selected button:first-child path { +#tools-menu li.selected button:first-child path, #tools-menu li.selected button:first-child ellipse { fill: $baseselectedicon; } diff --git a/js/FeatureToggles.js b/js/FeatureToggles.js index 5b77f57..e4e6fff 100644 --- a/js/FeatureToggles.js +++ b/js/FeatureToggles.js @@ -1,4 +1,4 @@ -const featureToggles = (function featureTogglesModule() { +/*const featureToggles = (function featureTogglesModule() { const ellipseToolLocalStorageKey = 'feature_ellipseTool'; @@ -30,4 +30,4 @@ const featureToggles = (function featureTogglesModule() { } })(); - +*/ diff --git a/js/ToolManager.js b/js/ToolManager.js index 634bbc2..dc966a8 100644 --- a/js/ToolManager.js +++ b/js/ToolManager.js @@ -6,6 +6,7 @@ const ToolManager = (() => { tools["eraser"] = new EraserTool("eraser", {type: 'html'}, switchTool); tools["rectangle"] = new RectangleTool("rectangle", {type: 'html'}, switchTool); tools["line"] = new LineTool("line", {type: 'html'}, switchTool); + tools["ellipse"] = new EllipseTool("ellipse", {type: 'html'}, switchTool); tools["fill"] = new FillTool("fill", {type: 'cursor', style: 'crosshair'}, switchTool); tools["eyedropper"] = new EyeDropperTool("eyedropper", {type: 'cursor', style: 'crosshair'}, switchTool); diff --git a/js/pixel-editor.js b/js/pixel-editor.js index f02d734..f8e6760 100644 --- a/js/pixel-editor.js +++ b/js/pixel-editor.js @@ -37,6 +37,7 @@ //=include tools/EraserTool.js //=include tools/LineTool.js //=include tools/RectangleTool.js +//=include tools/EllipseTool.js //=include tools/FillTool.js //=include tools/EyeDropperTool.js //=include tools/PanTool.js @@ -69,7 +70,7 @@ PresetModule.instrumentPresetMenu(); //when the page is done loading, you can get ready to start window.onload = function () { - featureToggles.onLoad(); + //featureToggles.onLoad(); ToolManager.currentTool().updateCursor(); diff --git a/js/tools/EllipseTool.js b/js/tools/EllipseTool.js new file mode 100644 index 0000000..e83adfb --- /dev/null +++ b/js/tools/EllipseTool.js @@ -0,0 +1,143 @@ +class EllipseTool extends DrawingTool { + // Saving the empty rect svg + emptyEllipseSVG = document.getElementById("ellipse-empty-button-svg"); + // and the full rect svg so that I can change them when the user changes rect modes + fullEllipseSVG = document.getElementById("ellipse-full-button-svg"); + // Current fill mode + currFillMode = 'empty'; + + switchFunction = null; + + 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 = 'fill'; + this.emptyEllipseSVG.setAttribute('display', 'none'); + this.fullEllipseSVG.setAttribute('display', 'visible'); + } + else { + this.currFillMode = 'empty' + this.emptyEllipseSVG.setAttribute('display', 'visible'); + this.fullEllipseSVG.setAttribute('display', 'none'); + } + else + this.switchFunction(this); + } + + onStart(mousePos) { + super.onStart(mousePos); + + // Putting the tmp layer on top of everything + currFile.TMPLayer.canvas.style.zIndex = parseInt(currFile.currentLayer.canvas.style.zIndex, 10) + 1; + + this.startMousePos[0] = Math.floor(mousePos[0] / currFile.zoom) + 0.5; + this.startMousePos[1] = Math.floor(mousePos[1] / currFile.zoom) + 0.5; + + new HistoryState().EditCanvas(); + } + + onDrag(mousePos, cursorTarget) { + + // Drawing the rect at the right position + this.drawRect(Math.floor(mousePos[0] / currFile.zoom) + 0.5, Math.floor(mousePos[1] / currFile.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); + let tmpContext = currFile.TMPLayer.context; + + let endRectX = Math.floor(mousePos[0] / currFile.zoom) + 0.5; + let endRectY = Math.floor(mousePos[1] / currFile.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 + 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); + } + + 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) { + // Getting the tmp context + let tmpContext = currFile.TMPLayer.context; + + // Clearing the tmp canvas + tmpContext.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.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/_ellipse.js b/js/tools/_ellipse.js deleted file mode 100644 index eb59c4d..0000000 --- a/js/tools/_ellipse.js +++ /dev/null @@ -1,144 +0,0 @@ -// Saving the empty rect svg -var emptyEllipseSVG = document.getElementById("ellipse-empty-button-svg"); -// and the full rect svg so that I can change them when the user changes rect modes -var fullEllipseSVG = document.getElementById("ellipse-full-button-svg"); - -// The start mode is empty ellipse -var ellipseDrawMode = 'empty'; -// I'm not drawing a ellipse at the beginning -var isDrawingEllipse = false; - -// Ellipse coordinates -let startEllipseX; -let startEllipseY; -let endEllipseX; -let endEllipseY; - -// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle -/** Starts drawing the ellipse, saves the start coordinates - * - * @param {*} mouseEvent - */ -function startEllipseDrawing(mouseEvent) { - // Putting the vfx layer on top of everything - VFXLayer.canvas.style.zIndex = parseInt(currentLayer.canvas.style.zIndex, 10) + 1;; - // Updating flag - isDrawingEllipse = true; - - // Saving the start coords of the ellipse - let cursorPos = Input.getCursorPosition(mouseEvent); - startEllipseX = Math.floor(cursorPos[0] / zoom) + 0.5; - startEllipseY = Math.floor(cursorPos[1] / zoom) + 0.5; - - drawEllipse(startEllipseX, startEllipseY); -} - -// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle -/** Updates the ellipse preview depending on the position of the mouse - * - * @param {*} mouseEvent The mouseEvent from which we'll get the mouse position - */ -function updateEllipseDrawing(mouseEvent) { - let pos = Input.getCursorPosition(mouseEvent); - - // Drawing the ellipse at the right position - drawEllipse(Math.round(pos[0] / zoom) + 0.5, Math.round(pos[1] / zoom) + 0.5); -} - -// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle -/** Finishes drawing the ellipse, decides the end coordinates and moves the preview ellipse to the - * current layer - * - * @param {*} mouseEvent event from which we'll get the mouse position - */ -function endEllipseDrawing(mouseEvent) { - // Getting the end position - let currentPos = Input.getCursorPosition(mouseEvent); - let vfxContext = VFXLayer.context; - - endEllipseX = Math.round(currentPos[0] / zoom) + 0.5; - endEllipseY = Math.round(currentPos[1] / zoom) + 0.5; - - // Inverting end and start (start must always be the top left corner) - if (endEllipseX < startEllipseX) { - let tmp = endEllipseX; - endEllipseX = startEllipseX; - startEllipseX = tmp; - } - // Same for the y - if (endEllipseY < startEllipseY) { - let tmp = endEllipseY; - endEllipseY = startEllipseY; - startEllipseY = tmp; - } - - // Resetting this - isDrawingEllipse = false; - // Drawing the ellipse - startEllipseY -= 0.5; - endEllipseY -= 0.5; - endEllipseX -= 0.5; - startEllipseX -= 0.5; - - // Setting the correct linewidth - currentLayer.context.lineWidth = tool.ellipse.brushSize; - - // Drawing the ellipse using 4 lines - currentLayer.drawLine(startEllipseX, startEllipseY, endEllipseX, startEllipseY, tool.ellipse.brushSize); - currentLayer.drawLine(endEllipseX, startEllipseY, endEllipseX, endEllipseY, tool.ellipse.brushSize); - currentLayer.drawLine(endEllipseX, endEllipseY, startEllipseX, endEllipseY, tool.ellipse.brushSize); - currentLayer.drawLine(startEllipseX, endEllipseY, startEllipseX, startEllipseY, tool.ellipse.brushSize); - - // If I have to fill it, I do so - if (ellipseDrawMode == 'fill') { - currentLayer.context.fillRect(startEllipseX, startEllipseY, endEllipseX - startEllipseX, endEllipseY - startEllipseY); - } - - // Clearing the vfx canvas - vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height); -} - -// TODO: [ELLIPSE] Make it draw ellipse instead of copy-pasted rectangle -/** Draws a ellipse with end coordinates given by x and y on the VFX layer (draws - * the preview for the ellipse tool) - * - * @param {*} x The current end x of the ellipse - * @param {*} y The current end y of the ellipse - */ -function drawEllipse(x, y) { - // Getting the vfx context - let vfxContext = VFXLayer.context; - - // Clearing the vfx canvas - vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height); - - // Drawing the ellipse - vfxContext.lineWidth = tool.ellipse.brushSize; - - // Drawing the ellipse - vfxContext.beginPath(); - if ((tool.ellipse.brushSize % 2 ) == 0) { - vfxContext.rect(startEllipseX - 0.5, startEllipseY - 0.5, x - startEllipseX, y - startEllipseY); - } - else { - vfxContext.rect(startEllipseX, startEllipseY, x - startEllipseX, y - startEllipseY); - } - - vfxContext.setLineDash([]); - vfxContext.stroke(); -} - -/** Sets the correct tool icon depending on its mode - * - */ -function setEllipseToolSvg() { - console.log("set eilipse svg"); - if (ellipseDrawMode == 'empty') { - emptyEllipseSVG.setAttribute('display', 'visible'); - fullEllipseSVG.setAttribute('display', 'none'); - } - else { - emptyEllipseSVG.setAttribute('display', 'none'); - fullEllipseSVG.setAttribute('display', 'visible'); - } -} diff --git a/svg/ellipse.svg b/svg/ellipse.svg index e2f7391..4c5d994 100644 --- a/svg/ellipse.svg +++ b/svg/ellipse.svg @@ -1,6 +1,9 @@ - - - - + + + + + + \ No newline at end of file diff --git a/svg/filledellipse.svg b/svg/filledellipse.svg index 803b053..8672a1e 100644 --- a/svg/filledellipse.svg +++ b/svg/filledellipse.svg @@ -1,22 +1,8 @@ - - - Layer 1 - - - - - - - - - - - - - - - - - - + + + + + + \ No newline at end of file diff --git a/views/tools-menu.hbs b/views/tools-menu.hbs index 4608518..77b22e6 100644 --- a/views/tools-menu.hbs +++ b/views/tools-menu.hbs @@ -24,10 +24,7 @@ - -