Added back brush with new tool system

This commit is contained in:
unsettledgames 2021-10-27 10:02:21 +02:00
parent 222228a6ce
commit 35cbe31a71
21 changed files with 217 additions and 125 deletions

View File

@ -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;
}

View File

@ -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<dictionary['color' + i] != null; i++) {
for (let i=0; dictionary['color' + i] != null; i++) {
ColorModule.addColor(dictionary['color'+i]);
}
// Removing the default colours
ColorModule.deleteColor(ColorModule.getCurrentPalette()[0]);
ColorModule.deleteColor(ColorModule.getCurrentPalette()[0]);
}
}

View File

@ -46,7 +46,7 @@ const Startup = (() => {
// 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');

View File

@ -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
}
})
})();

View File

@ -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':

View File

@ -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) {

View File

@ -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);
}

View File

@ -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]);
}
});
});
*/

View File

@ -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

View File

@ -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(){

View File

@ -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';
}
}

View File

@ -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) {

38
js/tools/BrushTool.js Normal file
View File

@ -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;
}
}

0
js/tools/EraserTool.js Normal file
View File

View File

0
js/tools/FillTool.js Normal file
View File

0
js/tools/LineTool.js Normal file
View File

0
js/tools/PanTool.js Normal file
View File

0
js/tools/RectagleTool.js Normal file
View File

0
js/tools/ZoomTool.js Normal file
View File

View File

@ -64,5 +64,6 @@ new Tool('zoom', {
});
//set a default tool
// REFACTOR: move to FileManager
var currentTool = tool.pencil;
var currentToolTemp = tool.pencil;