diff --git a/js/ColorModule.js b/js/ColorModule.js index b4170fe..6fc2554 100644 --- a/js/ColorModule.js +++ b/js/ColorModule.js @@ -246,6 +246,8 @@ const ColorModule = (() => { //if color is a string, then find the corresponding button if (typeof color === 'string') { + if (color[0] === '#') + color = color.substr(1, color.length - 1); //get all colors in palette let colors = document.getElementsByClassName('color-button'); @@ -255,6 +257,7 @@ const ColorModule = (() => { if (color == colors[i].jscolor.toString()) { //set color to the color button + currentPalette.splice(i, 1); color = colors[i]; break; } diff --git a/js/FileManager.js b/js/FileManager.js index e0cb000..4acb112 100644 --- a/js/FileManager.js +++ b/js/FileManager.js @@ -180,9 +180,14 @@ const FileManager = (() => { reader.onload = function (e) { let dictionary = JSON.parse(e.target.result); Startup.newPixel(dictionary['canvasWidth'], dictionary['canvasHeight'], dictionary); - for (let i=0; i { // Closing the "New Pixel dialogue" Dialogue.closeDialogue(); // Updating the cursor of the current tool - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); // The user is now able to export the Pixel document.getElementById('export-button').classList.remove('disabled'); diff --git a/js/ToolManager.js b/js/ToolManager.js index c28e2e8..5075f2e 100644 --- a/js/ToolManager.js +++ b/js/ToolManager.js @@ -1,14 +1,69 @@ const ToolManager = (() => { - /** What it should do - * - * - Listen to mouse events - * - Bind mouse events - * - Call tool functions - * - * - */ + brush = new BrushTool("brush", {type: 'html'}); + currTool = brush; + + Events.on("mouseup", window, onMouseUp); + Events.on("mousemove", window, onMouseMove); + Events.on("mousedown", window, onMouseDown); + + function onMouseDown(mouseEvent) { + if (!Startup.documentCreated()) + return; + + let mousePos = Input.getCursorPosition(mouseEvent); + console.log("here"); + switch(mouseEvent.which) { + case 1: + if (!Input.isDragging()) { + currTool.onStart(mousePos); + } + break; + case 2: + break; + case 3: + break; + default: + break; + } + } + + function onMouseMove(mouseEvent) { + if (!Startup.documentCreated()) + return; + let mousePos = Input.getCursorPosition(mouseEvent); + // Call the hover event + currTool.onHover(mousePos, mouseEvent.target); + + if (Input.isDragging()) { + currTool.onDrag(mousePos, mouseEvent.target); + } + } + + function onMouseUp(mouseEvent) { + if (!Startup.documentCreated()) + return; + let mousePos = Input.getCursorPosition(mouseEvent); + + switch(mouseEvent.which) { + case 0: + if (Input.isDragging()) { + currTool.onEnd(mousePos); + } + break; + case 1: + break; + case 2: + break; + default: + break; + } + } + + function currentTool() { + return currTool; + } return { - + currentTool } -}) \ No newline at end of file +})(); \ No newline at end of file diff --git a/js/TopMenuModule.js b/js/TopMenuModule.js index 54338bf..b549476 100644 --- a/js/TopMenuModule.js +++ b/js/TopMenuModule.js @@ -62,7 +62,7 @@ const TopMenuModule = (() => { Events.on('click', currSubmenuButton, cutSelectionTool); break; case 'Cancel': - Events.on('click', currSubmenuButton, tool.pencil.switchTo); + //Events.on('click', currSubmenuButton, tool.pencil.switchTo); break; //Help Menu case 'Settings': diff --git a/js/_changeZoom.js b/js/_changeZoom.js index 426616a..b4070b7 100644 --- a/js/_changeZoom.js +++ b/js/_changeZoom.js @@ -54,7 +54,7 @@ function changeZoom (direction, cursorLocation) { //resize canvas layers[0].resize(); // adjust brush size - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); // Adjust pixel grid thickness if (zoomed) { diff --git a/js/_drawLine.js b/js/_drawLine.js index ab2f392..0db0763 100644 --- a/js/_drawLine.js +++ b/js/_drawLine.js @@ -9,10 +9,10 @@ function line(x0,y0,x1,y1, brushSize) { while (true) { //set pixel // If the current tool is the brush - if (currentTool.name == 'pencil' || currentTool.name == 'rectangle' || currentTool.name == 'ellipse') { + if (ToolManager.currentTool().name == 'brush' || ToolManager.currentTool().name == 'rectangle' || ToolManager.currentTool().name == 'ellipse') { // I fill the rect currentLayer.context.fillRect(x0-Math.floor(brushSize/2), y0-Math.floor(brushSize/2), brushSize, brushSize); - } else if (currentTool.name == 'eraser') { + } else if (ToolManager.currentTool().name == 'eraser') { // In case I'm using the eraser I must clear the rect currentLayer.context.clearRect(x0-Math.floor(tool.eraser.brushSize/2), y0-Math.floor(tool.eraser.brushSize/2), tool.eraser.brushSize, tool.eraser.brushSize); } diff --git a/js/_mouseEvents.js b/js/_mouseEvents.js index f11636b..95bb100 100644 --- a/js/_mouseEvents.js +++ b/js/_mouseEvents.js @@ -1,6 +1,7 @@ // REFACTOR: let's keep this one global for now, unfortunately it's used by just some tools to keep track of // their state: I'd wait after we refactor the tools themselves before removing this variable, which should // ideally be updated in Input.js what a mess what a mess what a mess what a mess +/* var lastMouseMovePos; //mousedown - start drawing @@ -164,7 +165,7 @@ window.addEventListener("mouseup", function (mouseEvent) { currentTool = currentToolTemp; - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); var cursorLocation = Input.getCursorPosition(mouseEvent); currentTool.moveBrushPreview(cursorLocation); @@ -215,11 +216,6 @@ function draw (mouseEvent) { eyedropperPreview.style.display = 'none'; if (currentTool.name == 'pencil') { - //hide brush preview outside of canvas / canvas view - if (mouseEvent.target.className == 'drawingCanvas'|| mouseEvent.target.className == 'drawingCanvas') - brushPreview.style.visibility = 'visible'; - else - brushPreview.style.visibility = 'hidden'; //draw line to current pixel if (Input.isDragging()) { @@ -335,7 +331,7 @@ function draw (mouseEvent) { //fix offset so the cursor stays centered tool.pencil.moveBrushPreview(lastMouseClickPos); - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); } else if (currentTool.name == 'resizeeraser' && Input.isDragging()) { //get new brush size based on x distance from original clicking location @@ -350,7 +346,7 @@ function draw (mouseEvent) { //fix offset so the cursor stays centered tool.eraser.moveBrushPreview(lastMouseClickPos); - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); } else if (currentTool.name == 'resizerectangle' && Input.isDragging()) { //get new brush size based on x distance from original clicking location @@ -368,7 +364,7 @@ function draw (mouseEvent) { //fix offset so the cursor stays centered // TODO: [ELLIPSE] Do we need similar logic related to ellipse? tool.rectangle.moveBrushPreview(lastMouseClickPos); - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); } else if (currentTool.name == 'resizeline' && Input.isDragging()) { //get new brush size based on x distance from original clicking location @@ -383,7 +379,7 @@ function draw (mouseEvent) { //fix offset so the cursor stays centered tool.line.moveBrushPreview(lastMouseClickPos); - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); } else if (currentTool.name == 'rectselect') { if (Input.isDragging() && !isRectSelecting && mouseEvent.target.className == 'drawingCanvas') { @@ -399,7 +395,7 @@ function draw (mouseEvent) { } else if (currentTool.name == 'moveselection') { // Updating the cursor (move if inside rect, cross if not) - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); // If I'm dragging, I move the preview if (Input.isDragging() && cursorInSelectedArea()) { @@ -422,7 +418,7 @@ function draw (mouseEvent) { } if (mouseEvent.target.className == 'drawingCanvas') - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); else canvasView.style.cursor = 'default'; } @@ -444,4 +440,5 @@ canvasView.addEventListener("wheel", function(mouseEvent){ // Copying first layer's data into the other layers layers[i].copyData(layers[0]); } -}); \ No newline at end of file +}); +*/ \ No newline at end of file diff --git a/js/_rectSelect.js b/js/_rectSelect.js index f49095e..980a33e 100644 --- a/js/_rectSelect.js +++ b/js/_rectSelect.js @@ -82,7 +82,7 @@ function endRectSelection(mouseEvent) { isRectSelecting = false; // Updating the cursor - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); } /** Cuts the selection from its canvas and puts it in the tmp layer so it can be moved diff --git a/js/_toolButtons.js b/js/_toolButtons.js index e81bae0..03b98de 100644 --- a/js/_toolButtons.js +++ b/js/_toolButtons.js @@ -1,19 +1,4 @@ // REFACTOR: add to single Tool implementations -//pencil -Events.on('click',"pencil-button", function(){ - tool.pencil.switchTo(); -}, false); - -//pencil bigger -Events.on('click',"pencil-bigger-button", function(){ - tool.pencil.brushSize++; -}, false); - -//pencil smaller -Events.on('click',"pencil-smaller-button", function(){ - if(tool.pencil.brushSize > 1) - tool.pencil.brushSize--; -}, false); //eraser Events.on('click',"eraser-button", function(){ diff --git a/js/_tools.js b/js/_tools.js index 1bef501..2ceae3f 100644 --- a/js/_tools.js +++ b/js/_tools.js @@ -6,94 +6,117 @@ var tool = {}; class Tool { name = "AbstractTool"; + // Cursor and brush size cursorType = {}; + cursor = undefined; cursorHTMLElement = undefined; - currBrushSize = 1; - prevBrushSize = 1; + currSize = 1; + prevSize = 1; + // Useful coordinates startMousePos = {}; + currMousePos = {}; prevMousePos = {}; endMousePos = {}; - onSelect() { - - } - - onHover(cursorPosition) { - let toSub = 1; - // Prevents the brush to be put in the middle of pixels - if (this.currentBrushSize % 2 == 0) { - toSub = 0.5; - } - brushPreview.style.left = (Math.floor(cursorLocation[0] / zoom) * zoom + currentLayer.canvas.offsetLeft - this.currentBrushSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; - brushPreview.style.top = (Math.floor(cursorLocation[1] / zoom) * zoom + currentLayer.canvas.offsetTop - this.currentBrushSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; - } - - onDeselect() { - - } - - onStart() { - - } - - onDrag() { - - } - - onEnd() { - - } - - updateCursor2() { - - } + // HTML elements + mainButton = undefined; + biggerButton = undefined; + smallerButton = undefined; constructor (name, options) { - - //stores the name in object, only needed for legacy functions from when currentTool was just a string this.name = name; + this.cursorType = options; + } + onSelect() { + /* //copy options to this object if (options.cursor) { //passed statically as a string if (typeof options.cursor == 'string') this.cursor = options.cursor; //passed a function which should be used as a getter function if (typeof options.cursor == 'function') Object.defineProperty(this, 'cursor', { get: options.cursor}); + + if (options.imageCursor) this.cursor = "url(\'/pixel-editor/"+options.imageCursor+".png\'), auto"; + + if (options.brushPreview) { + this.brushPreview = true; + } + }*/ + } + + onHover(cursorLocation, cursorTarget) { + this.prevMousePos = this.currMousePos; + this.currMousePos = cursorLocation; + + let toSub = 1; + // Prevents the brush to be put in the middle of pixels + if (this.currSize % 2 == 0) { + toSub = 0.5; + } + + brushPreview.style.left = (Math.floor(cursorLocation[0] / zoom) * zoom + currentLayer.canvas.offsetLeft - this.currSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; + brushPreview.style.top = (Math.floor(cursorLocation[1] / zoom) * zoom + currentLayer.canvas.offsetTop - this.currSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; + + switch (this.cursorType.type) { + case 'html': + if (cursorTarget == 'drawingCanvas'|| cursorTarget.className == 'drawingCanvas') + brushPreview.style.visibility = 'visible'; + else + brushPreview.style.visibility = 'hidden'; + + brushPreview.style.display = 'block'; + brushPreview.style.width = this.currSize * zoom + 'px'; + brushPreview.style.height = this.currSize * zoom + 'px'; + break; + case 'cursor': + canvasView.style.cursor = this.cursor || 'default'; + break; + default: + break; } + } - if (options.imageCursor) this.cursor = "url(\'/pixel-editor/"+options.imageCursor+".png\'), auto"; + onDeselect() { - this.currentBrushSize = 1; - this.previousBrushSize = 1; - if (options.brushPreview) { - this.brushPreview = true; + } + + onStart(mousePos) { + this.startMousePos = mousePos; + } + + onDrag(mousePos) { + } + + onEnd(mousePos) { + this.endMousePos = mousePos; + } + + increaseSize() { + if (this.currSize < 128) { + this.currSize++; + this.updateCursor(); } - - //add to tool object so it can be referenced - tool[name] = this; } - get brushSize () { - return this.currentBrushSize; + decreaseSize() { + if (this.currSize > 0) { + this.currSize--; + this.updateCursor(); + } } - set brushSize (value) { - this.currentBrushSize = value; - this.updateCursor(); + get size() { + return this.currSize; } - //switch to this tool (replaced global changeTool()) switchTo () { // Ending any selection in progress - if (currentTool.name.includes("select") && !this.name.includes("select") && !selectionCanceled) { + /*if (currentTool.name.includes("select") && !this.name.includes("select") && !selectionCanceled) { endSelection(); - } - - //set tool and temp tje tje tpp <--- he's speaking the language of the gods, don't delete - currentTool = this; - currentToolTemp = this; + }*/ var tools = document.getElementById("tools-menu").children; @@ -114,16 +137,9 @@ class Tool { updateCursor () { //switch to that tools cursor canvasView.style.cursor = this.cursor || 'default'; - - //if the tool uses a brush preview, make it visible and update the size - if (this.brushPreview) { - //console.log('brush size',this.currentBrushSize) - brushPreview.style.display = 'block'; - brushPreview.style.width = this.currentBrushSize * zoom + 'px'; - brushPreview.style.height = this.currentBrushSize * zoom + 'px'; - } + //moveSelection - if (currentTool.name == 'moveselection') { + /*if (currentTool.name == 'moveselection') { if (cursorInSelectedArea()) { canMoveSelection = true; canvasView.style.cursor = 'move'; @@ -132,18 +148,8 @@ class Tool { else { canvasView.style.cursor = 'crosshair'; } - } + }*/ } - - moveBrushPreview(cursorLocation) { - let toSub = 1; - // Prevents the brush to be put in the middle of pixels - if (this.currentBrushSize % 2 == 0) { - toSub = 0.5; - } - brushPreview.style.left = (Math.floor(cursorLocation[0] / zoom) * zoom + currentLayer.canvas.offsetLeft - this.currentBrushSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; - brushPreview.style.top = (Math.floor(cursorLocation[1] / zoom) * zoom + currentLayer.canvas.offsetTop - this.currentBrushSize * zoom / 2 - zoom / 2 + toSub * zoom) + 'px'; - } } diff --git a/js/pixel-editor.js b/js/pixel-editor.js index 6eb47cd..8120763 100644 --- a/js/pixel-editor.js +++ b/js/pixel-editor.js @@ -10,6 +10,10 @@ //=include Dialogue.js //=include History.js +//=include _tools.js +//=include tools/*.js +//=include ToolManager.js + /**init**/ //=include _consts.js //=include Settings.js @@ -24,8 +28,6 @@ //=include _palettes.js /**functions**/ -//=include _tools.js -//=include tools/*.js //=include _changeZoom.js //=include ColorModule.js //=include _drawLine.js @@ -62,7 +64,7 @@ PresetModule.instrumentPresetMenu(); window.onload = function () { featureToggles.onLoad(); - currentTool.updateCursor(); + ToolManager.currentTool().updateCursor(); //check if there are any url parameters if (window.location.pathname.replace('/pixel-editor/','').length <= 1) { diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js new file mode 100644 index 0000000..cfa6991 --- /dev/null +++ b/js/tools/BrushTool.js @@ -0,0 +1,38 @@ +class BrushTool extends Tool { + constructor(name, options) { + super(name, options); + + // Selection button, brush size buttons + Events.on('click',"pencil-button", this.onSelect); + Events.on('click',"pencil-bigger-button", this.increaseSize.bind(this)); + Events.on('click',"pencil-smaller-button", this.decreaseSize.bind(this)); + } + + onStart(mousePos) { + super.onStart(mousePos); + this.startMousePos = mousePos; + } + + onDrag(mousePos, cursorTarget) { + super.onDrag(mousePos); + + if (cursorTarget === undefined) + return; + //draw line to current pixel + if (cursorTarget.className == 'drawingCanvas' || cursorTarget.className == 'drawingCanvas') { + line(Math.floor(this.prevMousePos[0]/zoom), + Math.floor(this.prevMousePos[1]/zoom), + Math.floor(this.currMousePos[0]/zoom), + Math.floor(this.currMousePos[1]/zoom), + this.currSize + ); + } + + currentLayer.updateLayerPreview(); + } + + onEnd(mousePos) { + super.onEnd(mousePos); + this.endMousePos = mousePos; + } +} \ No newline at end of file diff --git a/js/tools/EraserTool.js b/js/tools/EraserTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/EyeDropperTool.js b/js/tools/EyeDropperTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/FillTool.js b/js/tools/FillTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/LineTool.js b/js/tools/LineTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/PanTool.js b/js/tools/PanTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/RectagleTool.js b/js/tools/RectagleTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/ZoomTool.js b/js/tools/ZoomTool.js new file mode 100644 index 0000000..e69de29 diff --git a/js/tools/_all.js b/js/tools/_all.js index d706b82..b9e8fab 100644 --- a/js/tools/_all.js +++ b/js/tools/_all.js @@ -64,5 +64,6 @@ new Tool('zoom', { }); //set a default tool +// REFACTOR: move to FileManager var currentTool = tool.pencil; var currentToolTemp = tool.pencil; \ No newline at end of file