Merge pull request #6 from unsettledgames/master

Added rectangle tool and rectangular selection
This commit is contained in:
Lospec 2020-04-09 21:12:26 -04:00 committed by GitHub
commit a10453c7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1052 additions and 200 deletions

41
_ext/svg/fullrect.svg Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M497,51H15C6.716,51,0,57.716,0,66v380c0,8.284,6.716,15,15,15h482c8.284,0,15-6.716,15-15V66
C512,57.716,505.284,51,497,51z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 695 B

41
_ext/svg/rectangle.svg Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M497,51H15C6.716,51,0,57.716,0,66v380c0,8.284,6.716,15,15,15h482c8.284,0,15-6.716,15-15V66
C512,57.716,505.284,51,497,51z M482,431H30V81h452V431z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 719 B

108
_ext/svg/rectselect.svg Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M160.003,21.333h-42.667c-5.888,0-10.667,4.779-10.667,10.667s4.779,10.667,10.667,10.667h42.667
c5.909,0,10.667-4.779,10.667-10.667S165.913,21.333,160.003,21.333z"/>
</g>
</g>
<g>
<g>
<path d="M288.003,21.333h-42.667c-5.888,0-10.667,4.779-10.667,10.667s4.779,10.667,10.667,10.667h42.667
c5.909,0,10.667-4.779,10.667-10.667S293.913,21.333,288.003,21.333z"/>
</g>
</g>
<g>
<g>
<path d="M160.003,352h-42.667c-5.888,0-10.667,4.779-10.667,10.667s4.779,10.667,10.667,10.667h42.667
c5.909,0,10.667-4.779,10.667-10.667S165.913,352,160.003,352z"/>
</g>
</g>
<g>
<g>
<path d="M288.003,352h-42.667c-5.888,0-10.667,4.779-10.667,10.667s4.779,10.667,10.667,10.667h42.667
c5.888,0,10.667-4.779,10.667-10.667S293.913,352,288.003,352z"/>
</g>
</g>
<g>
<g>
<path d="M32.003,234.667c-5.909,0-10.667,4.779-10.667,10.667V288c0,5.888,4.779,10.667,10.667,10.667S42.67,293.888,42.67,288
v-42.667C42.67,239.445,37.913,234.667,32.003,234.667z"/>
</g>
</g>
<g>
<g>
<path d="M32.003,106.667c-5.909,0-10.667,4.779-10.667,10.667V160c0,5.888,4.779,10.667,10.667,10.667
c5.909,0,10.667-4.779,10.667-10.667v-42.667C42.67,111.445,37.913,106.667,32.003,106.667z"/>
</g>
</g>
<g>
<g>
<path d="M373.337,234.667c-5.888,0-10.667,4.779-10.667,10.667V288c0,5.888,4.779,10.667,10.667,10.667
c5.888,0,10.667-4.779,10.667-10.667v-42.667C384.003,239.445,379.246,234.667,373.337,234.667z"/>
</g>
</g>
<g>
<g>
<path d="M373.337,106.667c-5.909,0-10.667,4.779-10.667,10.667V160c0,5.888,4.779,10.667,10.667,10.667
c5.888,0,10.667-4.779,10.667-10.667v-42.667C384.003,111.445,379.246,106.667,373.337,106.667z"/>
</g>
</g>
<g>
<g>
<path d="M394.67,0h-42.667c-5.888,0-10.667,4.779-10.667,10.667v42.667c0,5.888,4.779,10.667,10.667,10.667h42.667
c5.909,0,10.667-4.779,10.667-10.667V10.667C405.337,4.779,400.579,0,394.67,0z"/>
</g>
</g>
<g>
<g>
<path d="M53.337,0H10.67C4.782,0,0.003,4.779,0.003,10.667v42.667C0.003,59.221,4.782,64,10.67,64h42.667
c5.909,0,10.667-4.779,10.667-10.667V10.667C64.003,4.779,59.246,0,53.337,0z"/>
</g>
</g>
<g>
<g>
<path d="M53.337,330.667H10.67c-5.888,0-10.667,4.779-10.667,10.667V384c0,5.888,4.779,10.667,10.667,10.667h42.667
c5.909,0,10.667-4.779,10.667-10.667v-42.667C64.003,335.445,59.246,330.667,53.337,330.667z"/>
</g>
</g>
<g>
<g>
<path d="M506.521,385.344l-192-106.667c-3.968-2.197-8.875-1.664-12.224,1.323c-3.392,2.987-4.544,7.765-2.859,11.968
l85.333,213.333c1.6,4.011,5.461,6.656,9.771,6.699c0.043,0,0.085,0,0.128,0c4.267,0,8.128-2.539,9.813-6.464l30.315-70.741
l70.741-30.315c3.733-1.6,6.229-5.205,6.443-9.259C512.195,391.168,510.062,387.328,506.521,385.344z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -52,6 +52,7 @@ svg {
position: fixed;
display:none;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.64);
background-color:transparent;
}
#checkerboard {
@ -63,6 +64,16 @@ svg {
background:transparent;
}
#tmp-canvas {
z-index:3;
background:transparent;
}
#vfx-canvas {
z-index:-5000;
background:transparent;
}
#eyedropper-preview {
position: absolute;
width: 45px;
@ -429,13 +440,15 @@ svg {
#tools-menu li button#pencil-bigger-button,
#tools-menu li button#zoom-in-button,
#tools-menu li button#eraser-bigger-button{
#tools-menu li button#eraser-bigger-button,
#tools-menu li button#rectangle-bigger-button{
left: 0;
}
#tools-menu li button#pencil-smaller-button,
#tools-menu li button#zoom-out-button,
#tools-menu li button#eraser-smaller-button{
#tools-menu li button#eraser-smaller-button,
#tools-menu li button#rectangle-smaller-button{
right: 0;
}
@ -444,7 +457,9 @@ svg {
#tools-menu li.selected button#zoom-in-button,
#tools-menu li.selected button#zoom-out-button,
#tools-menu li.selected button#eraser-bigger-button,
#tools-menu li.selected button#eraser-smaller-button{
#tools-menu li.selected button#eraser-smaller-button,
#tools-menu li.selected button#rectangle-bigger-button,
#tools-menu li.selected button#rectangle-smaller-button{
display: block;
}

BIN
images/layout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/rectangle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
images/rectselect.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,5 +1,8 @@
function changeTool (selectedTool) {
// Ending any selection in progress
if (currentTool.includes("select") && !selectedTool.includes("select") && !selectionCanceled) {
endSelection();
}
//set tool and temp tje tje tpp;
currentTool = selectedTool;
currentToolTemp = selectedTool;

View File

@ -10,6 +10,7 @@ function clickedColor (e){
//set current color
currentLayer.context.fillStyle = this.style.backgroundColor;
currentGlobalColor = this.style.backgroundColor;
//make color selected
e.target.parentElement.classList.add('selected');

View File

@ -28,9 +28,6 @@ function colorChanged(e) {
var newColor = hexToRgb(e.target.value);
var oldColor = e.target.oldColor;
console.log('newColor',newColor)
console.log('oldColor',oldColor)
//save undo state
//saveHistoryState({type: 'colorchange', newColor: e.target.value, oldColor: rgbToHex(oldColor), canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
new HistoryStateEditColor(e.target.value.toLowerCase(), rgbToHex(oldColor));
@ -50,15 +47,14 @@ function colorChanged(e) {
//loop through all colors in palette
for (var i = 0; i < colors.length; i++) {
console.log('%c'+newColorHex +' '+ colors[i].jscolor.toString(), colorCheckingStyle)
//if generated color matches this color
if (newColorHex == colors[i].jscolor.toString()) {
console.log('%ccolor already exists'+(colors[i].parentElement.classList.contains('jscolor-active')?' (but is the current color)':''), colorCheckingStyle);
//console.log('%ccolor already exists'+(colors[i].parentElement.classList.contains('jscolor-active')?' (but is the current color)':''), colorCheckingStyle);
//if the color isnt the one that has the picker currently open
if (!colors[i].parentElement.classList.contains('jscolor-active')) {
console.log('%cColor is duplicate', colorCheckingStyle)
//console.log('%cColor is duplicate', colorCheckingStyle)
//show the duplicate color warning
duplicateColorWarning.style.visibility = 'visible';
@ -83,13 +79,12 @@ function colorChanged(e) {
//set new old color to changed color
e.target.oldColor = newColor;
console.log(e.target.colorElement);
//if this is the current color, update the drawing color
if (e.target.colorElement.parentElement.classList.contains('selected')) {
console.log('this color is the current color');
context.fillStyle = '#'+ rgbToHex(newColor.r,newColor.g,newColor.b);
//console.log('this color is the current color');
context.fillStyle = currentColor;
}
/* this is wrong and bad
if (settings.switchToChangedColor) {

2
js/_consts.js Normal file
View File

@ -0,0 +1,2 @@
const MIN_Z_INDEX = -5000;
const MAX_Z_INDEX = 5000;

View File

@ -1,5 +1,5 @@
//draw a line between two points on canvas
function line(x0,y0,x1,y1) {
function line(x0,y0,x1,y1, brushSize) {
var dx = Math.abs(x1-x0);
var dy = Math.abs(y1-y0);
@ -10,7 +10,7 @@ function line(x0,y0,x1,y1) {
while (true) {
//set pixel
// If the current tool is the brush
if (currentTool == 'pencil') {
if (currentTool == 'pencil' || currentTool == 'rectangle') {
// I fill the rect
currentLayer.context.fillRect(x0-Math.floor(brushSize/2), y0-Math.floor(brushSize/2), brushSize, brushSize);
} else if (currentTool == 'eraser') {
@ -18,6 +18,34 @@ function line(x0,y0,x1,y1) {
currentLayer.context.clearRect(x0-Math.floor(eraserSize/2), y0-Math.floor(eraserSize/2), eraserSize, eraserSize);
}
//if we've reached the end goal, exit the loop
if ((x0==x1) && (y0==y1)) break;
var e2 = 2*err;
if (e2 >-dy) {err -=dy; x0+=sx;}
if (e2 < dx) {err +=dx; y0+=sy;}
}
}
//draw a line between two points on canvas
function lineOnLayer(x0,y0,x1,y1, brushSize, context) {
var dx = Math.abs(x1-x0);
var dy = Math.abs(y1-y0);
var sx = (x0 < x1 ? 1 : -1);
var sy = (y0 < y1 ? 1 : -1);
var err = dx-dy;
while (true) {
//set pixel
// If the current tool is the brush
if (currentTool == 'pencil' || currentTool == 'rectangle') {
// I fill the rect
context.fillRect(x0-Math.floor(brushSize/2), y0-Math.floor(brushSize/2), brushSize, brushSize);
} else if (currentTool == 'eraser') {
// In case I'm using the eraser I must clear the rect
context.clearRect(x0-Math.floor(eraserSize/2), y0-Math.floor(eraserSize/2), eraserSize, eraserSize);
}
//if we've reached the end goal, exit the loop
if ((x0==x1) && (y0==y1)) break;
var e2 = 2*err;

View File

@ -2,6 +2,7 @@
function getCursorPosition(e) {
var x;
var y;
if (e.pageX != undefined && e.pageY != undefined) {
x = e.pageX;
y = e.pageY;
@ -14,5 +15,29 @@ function getCursorPosition(e) {
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
return [x,y];
}
// TODO: apply the function below to every getCursorPosition call
// TODO: FIX THIS BELOW
//get cursor position relative to canvas
function getCursorPositionRelative(e, layer) {
var x;
var y;
if (e.pageX != undefined && e.pageY != undefined) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= layer.canvas.offsetLeft;
y -= layer.canvas.offsetTop;
return [x,y];
}

View File

@ -1,65 +1,86 @@
var spacePressed = false;
function KeyPress(e) {
var keyboardEvent = window.event? event : e;
//if the user is typing in an input field, ignore these hotkeys
if (document.activeElement.tagName == 'INPUT') return;
//if no document has been created yet,
//orthere is a dialog box open
//ignore hotkeys
if (!documentCreated || dialogueOpen) return;
//
switch (keyboardEvent.keyCode) {
//pencil tool - 1, b
case 49: case 66:
var keyboardEvent = window.event? event : e;
//if the user is typing in an input field, ignore these hotkeys
if (document.activeElement.tagName == 'INPUT') return;
//if no document has been created yet,
//orthere is a dialog box open
//ignore hotkeys
if (!documentCreated || dialogueOpen) return;
//
if (e.key === "Escape") {
if (!selectionCanceled) {
endSelection();
changeTool('pencil');
break;
//fill tool - 2, f
case 50: case 70:
changeTool('fill');
break;
//eyedropper - 3, e
case 51: case 69:
changeTool('eyedropper');
break;
//pan - 4, p, m
case 52: case 80: case 77:
changeTool('pan');
break;
//zoom - 5
case 53:
changeTool('zoom');
break;
// eraser -6, r
case 54: case 82:
console.log("Pressed r");
changeTool('eraser');
break;
//Z
case 90:
console.log('PRESSED Z ', keyboardEvent.ctrlKey)
//CTRL+ALT+Z redo
if (keyboardEvent.altKey && keyboardEvent.ctrlKey)
redo();
//CTRL+Z undo
else if (keyboardEvent.ctrlKey)
undo();
//Z switch to zoom tool
else
}
}
else {
switch (keyboardEvent.keyCode) {
//pencil tool - 1, b
case 49: case 66:
changeTool('pencil');
break;
//fill tool - 2, f
case 50: case 70:
changeTool('fill');
break;
//eyedropper - 3, e
case 51: case 69:
changeTool('eyedropper');
break;
//pan - 4, p,
case 52: case 80:
changeTool('pan');
break;
//zoom - 5
case 53:
changeTool('zoom');
break;
//redo - ctrl y
case 89:
if (keyboardEvent.ctrlKey)
redo();
break;
case 32:
spacePressed=true;
break;
}
break;
// eraser -6, r
case 54: case 82:
console.log("Pressed r");
changeTool('eraser');
break;
// Rectangular selection
case 77: case 109:
changeTool('rectselect');
break;
//Z
case 90:
console.log('PRESSED Z ', keyboardEvent.ctrlKey)
//CTRL+ALT+Z redo
if (keyboardEvent.altKey && keyboardEvent.ctrlKey)
redo();
if (!selectionCanceled) {
endSelection();
changeTool('pencil');
}
//CTRL+Z undo
else if (keyboardEvent.ctrlKey) {
undo();
if (!selectionCanceled) {
endSelection();
changeTool('pencil');
}
}
//Z switch to zoom tool
else
changeTool('zoom');
break;
//redo - ctrl y
case 89:
if (keyboardEvent.ctrlKey)
redo();
break;
case 32:
spacePressed=true;
break;
}
}
}
document.onkeydown = KeyPress;

View File

@ -1,48 +1,61 @@
/** Handler class for a single canvas (a single layer)
*
* @param width Canvas width
* @param height Canvas height
* @param canvas HTML canvas element
*/
function Canvas(width, height, canvas) {
this.canvasSize = [width, height],
this.canvas = canvas,
this.context = this.canvas.getContext("2d"),
// Initializes the canvas
this.initialize = function() {
var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75);
var maxVerticalZoom = Math.floor(window.innerHeight/this.canvasSize[1]*0.75);
zoom = Math.min(maxHorizontalZoom,maxVerticalZoom);
if (zoom < 1) zoom = 1;
//resize canvas
this.canvas.width = this.canvasSize[0];
this.canvas.height = this.canvasSize[1];
this.canvas.style.width = (this.canvas.width*zoom)+'px';
this.canvas.style.height = (this.canvas.height*zoom)+'px';
//unhide canvas
this.canvas.style.display = 'block';
//center canvas in window
this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px';
this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px';
},
// Resizes canvas
this.resize = function() {
let newWidth = (this.canvas.width * zoom) + 'px';
let newHeight = (this.canvas.height *zoom)+ 'px';
this.canvas.style.width = newWidth;
this.canvas.style.height = newHeight;
},
// Copies the otherCanvas' position and size
this.copyData = function(otherCanvas) {
this.canvas.style.width = otherCanvas.canvas.style.width;
this.canvas.style.height = otherCanvas.canvas.style.height;
this.canvas.style.left = otherCanvas.canvas.style.left;
this.canvas.style.top = otherCanvas.canvas.style.top;
}
/** TODO LIST FOR LAYERS
- move the tmp layer so that it's always right below the active layer
- when the move tool is selected (to move a selection), the tmp layer must be put right above the
active layer to show a preview
- mouse events will always have at least a canvas target, so evey time there's an event, we'll have to check
the actual element type instead of the current layer and then apply the tool on the currentLayer, not on
the first one in order of z-index
*/
/** Handler class for a single canvas (a single layer)
*
* @param width Canvas width
* @param height Canvas height
* @param canvas HTML canvas element
*/
function Layer(width, height, canvas) {
this.canvasSize = [width, height],
this.canvas = canvas,
this.context = this.canvas.getContext("2d"),
// Initializes the canvas
this.initialize = function() {
var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75);
var maxVerticalZoom = Math.floor(window.innerHeight/this.canvasSize[1]*0.75);
zoom = Math.min(maxHorizontalZoom,maxVerticalZoom);
if (zoom < 1) zoom = 1;
//resize canvas
this.canvas.width = this.canvasSize[0];
this.canvas.height = this.canvasSize[1];
this.canvas.style.width = (this.canvas.width*zoom)+'px';
this.canvas.style.height = (this.canvas.height*zoom)+'px';
//unhide canvas
this.canvas.style.display = 'block';
//center canvas in window
this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px';
this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px';
this.context.imageSmoothingEnabled = false;
this.context.mozImageSmoothingEnabled = false;
},
// Resizes canvas
this.resize = function() {
let newWidth = (this.canvas.width * zoom) + 'px';
let newHeight = (this.canvas.height *zoom)+ 'px';
this.canvas.style.width = newWidth;
this.canvas.style.height = newHeight;
},
// Copies the otherCanvas' position and size
this.copyData = function(otherCanvas) {
this.canvas.style.width = otherCanvas.canvas.style.width;
this.canvas.style.height = otherCanvas.canvas.style.height;
this.canvas.style.left = otherCanvas.canvas.style.left;
this.canvas.style.top = otherCanvas.canvas.style.top;
}
}

View File

@ -1,6 +1,12 @@
var currentMouseEvent;
// TODO: replace every position calculation with lastMousePos
var lastMousePos;
//mousedown - start drawing
window.addEventListener("mousedown", function (mouseEvent) {
// Saving the event in case something else needs it
currentMouseEvent = mouseEvent;
canDraw = true;
//if no document has been created yet, or this is a dialog open
if (!documentCreated || dialogueOpen) return;
@ -10,31 +16,43 @@ window.addEventListener("mousedown", function (mouseEvent) {
lastPos = getCursorPosition(mouseEvent);
dragging = true;
//left or right click
//left or right click ?
if (mouseEvent.which == 1) {
if (spacePressed)
currentTool = 'pan';
else if (mouseEvent.altKey)
currentTool = 'eyedropper';
else if (mouseEvent.target == currentLayer.canvas && (currentTool == 'pencil' || currentTool == 'eraser'))
else if (mouseEvent.target.className == 'drawingCanvas' &&
(currentTool == 'pencil' || currentTool == 'eraser' || currentTool == 'rectangle'))
new HistoryStateEditCanvas();
else if (currentTool == 'moveselection') {
if (!cursorInSelectedArea()) {
changeTool('pencil');
canDraw = false;
}
}
//saveHistoryState({type: 'canvas', canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
updateCursor();
draw(mouseEvent);
if (canDraw) {
draw(mouseEvent);
}
}
else if (currentTool == 'pencil' && mouseEvent.which == 3) {
currentTool = 'resize-brush';
prevBrushSize = brushSize;
prevBrushSize = pencilSize;
}
else if (currentTool == 'eraser' && mouseEvent.which == 3) {
currentTool = 'resize-eraser';
prevEraserSize = eraserSize;
}
if (currentTool == 'eyedropper' && mouseEvent.target == currentLayer.canvas)
else if (currentTool == 'rectangle' && mouseEvent.which == 3) {
currentTool = 'resize-rectangle';
prevRectangleSize = rectangleSize;
}
if (currentTool == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas')
eyedropperPreview.style.display = 'block';
return false;
@ -44,47 +62,45 @@ window.addEventListener("mousedown", function (mouseEvent) {
//mouseup - end drawing
window.addEventListener("mouseup", function (mouseEvent) {
// Saving the event in case something else needs it
currentMouseEvent = mouseEvent;
closeMenu();
if (!documentCreated || dialogueOpen) return;
if (currentTool == 'eyedropper' && mouseEvent.target == currentLayer.canvas) {
if (currentTool == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas') {
var cursorLocation = getCursorPosition(mouseEvent);
var selectedColor = context.getImageData(Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom),1,1);
var newColor = rgbToHex(selectedColor.data[0],selectedColor.data[1],selectedColor.data[2]);
console.log(newColor);
var newColor = rgbToHex(selectedColor.data[0],selectedColor.data[1],selectedColor.data[2]);
currentGlobalColor = "#" + newColor;
var colors = document.getElementsByClassName('color-button');
for (var i = 0; i < colors.length; i++) {
console.log(colors[i].jscolor.toString());
//if picked color matches this color
if (newColor == colors[i].jscolor.toString()) {
console.log('color found');
//remove current color selection
var selectedColor = document.querySelector("#colors-menu li.selected")
if (selectedColor) selectedColor.classList.remove("selected");
//set current color
context.fillStyle = '#'+newColor;
//make color selected
colors[i].parentElement.classList.add('selected');
//hide eyedropper
eyedropperPreview.style.display = 'none';
}
}
for (var i = 0; i < colors.length; i++) {
console.log(colors[i].jscolor.toString());
//if picked color matches this color
if (newColor == colors[i].jscolor.toString()) {
console.log('color found');
//remove current color selection
var selectedColor = document.querySelector("#colors-menu li.selected")
if (selectedColor) selectedColor.classList.remove("selected");
//set current color
context.fillStyle = '#'+newColor;
//make color selected
colors[i].parentElement.classList.add('selected');
//hide eyedropper
eyedropperPreview.style.display = 'none';
}
}
}
else if (currentTool == 'fill' && mouseEvent.target == currentLayer.canvas) {
else if (currentTool == 'fill' && mouseEvent.target.className == 'drawingCanvas') {
console.log('filling')
//if you clicked on anything but the canvas, do nothing
if (!mouseEvent.target == currentLayer.canvas) return;
//get cursor postion
var cursorLocation = getCursorPosition(mouseEvent);
@ -96,7 +112,7 @@ window.addEventListener("mouseup", function (mouseEvent) {
//fill starting at the location
fill(cursorLocation);
}
else if (currentTool == 'zoom' && mouseEvent.target == canvasView) {
else if (currentTool == 'zoom' && mouseEvent.target.className == 'drawingCanvas') {
let mode;
if (mouseEvent.which == 1){
mode = "in";
@ -111,6 +127,12 @@ window.addEventListener("mouseup", function (mouseEvent) {
layers[i].copyData(layers[0]);
}
}
else if (currentTool == 'rectselect' && isRectSelecting) {
endRectSelection(mouseEvent);
}
else if (currentTool == 'rectangle') {
endRectDrawing(mouseEvent);
}
dragging = false;
currentTool = currentToolTemp;
@ -121,10 +143,16 @@ window.addEventListener("mouseup", function (mouseEvent) {
}, false);
// OPTIMIZABLE: redundant || mouseEvent.target.className in currentTool ifs
//mouse is moving on canvas
window.addEventListener("mousemove", draw, false);
function draw (mouseEvent) {
var cursorLocation = getCursorPosition(mouseEvent);
lastMousePos = getCursorPosition(mouseEvent);
// Saving the event in case something else needs it
currentMouseEvent = mouseEvent;
var cursorLocation = lastMousePos;
//if a document hasnt yet been created, exit this function
if (!documentCreated || dialogueOpen) return;
@ -133,21 +161,20 @@ function draw (mouseEvent) {
eyedropperPreview.style.display = 'none';
if (currentTool == 'pencil') {
//move the brush preview
brushPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - brushSize * zoom / 2 + 'px';
brushPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - brushSize * zoom / 2 + 'px';
brushPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - pencilSize * zoom / 2 + 'px';
brushPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - pencilSize * zoom / 2 + 'px';
//hide brush preview outside of canvas / canvas view
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView)
if (mouseEvent.target.className == 'drawingCanvas'|| mouseEvent.target.className == 'drawingCanvas')
brushPreview.style.visibility = 'visible';
else
brushPreview.style.visibility = 'hidden';
//draw line to current pixel
if (dragging) {
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView) {
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom));
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas') {
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom), pencilSize);
lastPos = cursorLocation;
}
}
@ -168,19 +195,38 @@ function draw (mouseEvent) {
brushPreview.style.top = cursorLocation[1] + canvas.offsetTop - eraserSize * zoom / 2 + 'px';
//hide brush preview outside of canvas / canvas view
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView)
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas')
brushPreview.style.visibility = 'visible';
else
brushPreview.style.visibility = 'hidden';
//draw line to current pixel
if (dragging) {
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView) {
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom));
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas') {
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom), eraserSize);
lastPos = cursorLocation;
}
}
}
else if (currentTool == 'rectangle')
{
//move the brush preview
brushPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - rectangleSize * zoom / 2 + 'px';
brushPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - rectangleSize * zoom / 2 + 'px';
//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';
if (!isDrawingRect && dragging) {
startRectDrawing(mouseEvent);
}
else if (dragging){
updateRectDrawing(mouseEvent);
}
}
else if (currentTool == 'pan' && dragging) {
// Setting first layer position
setCanvasOffset(layers[0].canvas, layers[0].canvas.offsetLeft + (cursorLocation[0] - lastPos[0]), layers[0].canvas.offsetTop + (cursorLocation[1] - lastPos[1]));
@ -189,8 +235,9 @@ function draw (mouseEvent) {
layers[i].copyData(layers[0]);
}
}
else if (currentTool == 'eyedropper' && dragging && mouseEvent.target == currentLayer.canvas) {
else if (currentTool == 'eyedropper' && dragging && mouseEvent.target.className == 'drawingCanvas') {
var selectedColor = context.getImageData(Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom),1,1).data;
eyedropperPreview.style.borderColor = '#'+rgbToHex(selectedColor[0],selectedColor[1],selectedColor[2]);
eyedropperPreview.style.display = 'block';
@ -212,11 +259,11 @@ function draw (mouseEvent) {
var newBrushSize = prevBrushSize + brushSizeChange;
//set the brush to the new size as long as its bigger than 1
brushSize = Math.max(1,newBrushSize);
pencilSize = Math.max(1,newBrushSize);
//fix offset so the cursor stays centered
brushPreview.style.left = lastPos[0] + currentLayer.canvas.offsetLeft - brushSize * zoom / 2 + 'px';
brushPreview.style.top = lastPos[1] + currentLayer.canvas.offsetTop - brushSize * zoom / 2 + 'px';
brushPreview.style.left = lastPos[0] + currentLayer.canvas.offsetLeft - pencilSize * zoom / 2 + 'px';
brushPreview.style.top = lastPos[1] + currentLayer.canvas.offsetTop - pencilSize * zoom / 2 + 'px';
updateCursor();
}
@ -237,6 +284,45 @@ function draw (mouseEvent) {
updateCursor();
}
else if (currentTool == 'resize-rectangle' && dragging) {
//get new brush size based on x distance from original clicking location
var distanceFromClick = cursorLocation[0] - lastPos[0];
//var roundingAmount = 20 - Math.round(distanceFromClick/10);
//this doesnt work in reverse... because... it's not basing it off of the brush size which it should be
var rectangleSizeChange = Math.round(distanceFromClick/10);
var newRectangleSize = prevRectangleSize + rectangleSizeChange;
//set the brush to the new size as long as its bigger than 1
rectangleSize = Math.max(1,newRectangleSize);
//fix offset so the cursor stays centered
brushPreview.style.left = lastPos[0] + currentLayer.canvas.offsetLeft - rectangleSize * zoom / 2 + 'px';
brushPreview.style.top = lastPos[1] + currentLayer.canvas.offsetTop - rectangleSize * zoom / 2 + 'px';
updateCursor();
}
else if (currentTool == 'rectselect') {
if (dragging && !isRectSelecting && mouseEvent.target.className == 'drawingCanvas') {
isRectSelecting = true;
console.log("cominciata selezione su " + mouseEvent.target.className);
startRectSelection(mouseEvent);
}
else if (dragging && isRectSelecting) {
updateRectSelection(mouseEvent);
}
else if (isRectSelecting) {
endRectSelection();
}
}
else if (currentTool == 'moveselection') {
// Updating the cursor (move if inside rect, cross if not)
updateCursor();
// If I'm dragging, I move the preview
if (dragging && cursorInSelectedArea()) {
updateMovePreview(mouseEvent);
}
}
}
//mousewheel scrroll

72
js/_move.js Normal file
View File

@ -0,0 +1,72 @@
var imageDataToMove;
var originalDataPosition;
var canMoveSelection = false;
var lastMovePos;
var selectionCanceled = true;
var firstTimeMove = true;
// TODO: move with arrows
function updateMovePreview(mouseEvent) {
// ISSUE
selectionCanceled = false;
if (firstTimeMove) {
cutSelection(mouseEvent);
}
firstTimeMove = false;
lastMousePos = getCursorPosition(mouseEvent);
// clear the entire tmp layer
TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height);
// put the image data with offset
TMPLayer.context.putImageData(
imageDataToMove,
Math.round(lastMousePos[0] / zoom - imageDataToMove.width / 2),
Math.round(lastMousePos[1] / zoom - imageDataToMove.height / 2));
lastMovePos = lastMousePos;
moveSelection(lastMousePos[0] / zoom, lastMousePos[1] / zoom, imageDataToMove.width, imageDataToMove.height)
}
function endSelection() {
TMPLayer.context.clearRect(0, 0, TMPLayer.canvas.width, TMPLayer.canvas.height);
VFXLayer.context.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height);
if (imageDataToMove !== undefined) {
let underlyingImageData = currentLayer.context.getImageData(startX, startY, endX - startX, endY - startY);
for (let i=0; i<underlyingImageData.data.length; i+=4) {
let currentMovePixel = [
imageDataToMove.data[i], imageDataToMove.data[i+1],
imageDataToMove.data[i+2], imageDataToMove.data[i+3]
];
let currentUnderlyingPixel = [
underlyingImageData.data[i], underlyingImageData.data[i+1],
underlyingImageData.data[i+2], underlyingImageData.data[i+3]
];
if (isPixelEmpty(currentMovePixel)) {
if (!isPixelEmpty(underlyingImageData)) {
imageDataToMove.data[i] = currentUnderlyingPixel[0];
imageDataToMove.data[i+1] = currentUnderlyingPixel[1];
imageDataToMove.data[i+2] = currentUnderlyingPixel[2];
imageDataToMove.data[i+3] = currentUnderlyingPixel[3];
}
}
}
if (lastMovePos !== undefined) {
currentLayer.context.putImageData(
imageDataToMove,
Math.round(lastMovePos[0] / zoom - imageDataToMove.width / 2),
Math.round(lastMovePos[1] / zoom - imageDataToMove.height / 2));
}
}
selectionCanceled = true;
isRectSelecting = false;
firstTimeMove = true;
imageDataToMove = undefined;
}

View File

@ -1,16 +1,27 @@
function newPixel (width, height, palette) {
currentLayer = new Canvas(width, height, canvas);
// Setting the current layer
currentLayer = new Layer(width, height, canvas);
currentLayer.initialize();
checkerBoard = new Canvas(width, height, checkerBoardCanvas);
// Adding the checkerboard behind it
checkerBoard = new Layer(width, height, checkerBoardCanvas);
checkerBoard.initialize();
// Creating the vfx layer on top of everything
VFXLayer = new Layer(width, height, VFXCanvas);
VFXLayer.initialize();
TMPLayer = new Layer(width, height, TMPCanvas);
TMPLayer.initialize();
canvasSize = currentLayer.canvasSize;
// Adding the first layer and the checkerboard to the list of layers
layers.push(VFXLayer);
layers.push(TMPLayer);
layers.push(currentLayer);
layers.push(checkerBoard);
//remove current palette
colors = document.getElementsByClassName('color-button');
while (colors.length > 0) {
@ -55,6 +66,7 @@ function newPixel (width, height, palette) {
//set current drawing color as foreground color
currentLayer.context.fillStyle = '#'+defaultForegroundColor;
currentGlobalColor = '#' + defaultForegroundColor;
selectedPalette = 'none';
}

View File

@ -0,0 +1,7 @@
function isPixelEmpty(pixel) {
if ((pixel[0] == 0 && pixel[1] == 0 && pixel[2] == 0) || pixel[3] == 0) {
return true;
}
return false;
}

151
js/_rectSelect.js Normal file
View File

@ -0,0 +1,151 @@
var isRectSelecting = false;
let startX;
let startY;
let endX;
let endY;
function startRectSelection(mouseEvent) {
// Saving the canvas
new HistoryStateEditCanvas();
// Putting the vfx layer on top of everything
VFXCanvas.style.zIndex = MAX_Z_INDEX;
// Saving the start coords of the rect
let cursorPos = getCursorPosition(mouseEvent);
startX = Math.round(cursorPos[0] / zoom) - 0.5;
startY = Math.round(cursorPos[1] / zoom) - 0.5;
// Avoiding external selections
if (startX < 0) {
startX = 0;
}
else if (startX > currentLayer.canvas.width) {
startX = currentLayer.canvas.width;
}
if (startY < 0) {
startY = 0;
}
else if (startY > currentLayer.canvas.height) {
startY = currentLayer.canvas.height;
}
// Drawing the rect
drawRect(startX, startY);
selectionCanceled = false;
}
function updateRectSelection(mouseEvent) {
let pos = getCursorPosition(mouseEvent);
// Drawing the rect
drawRect(Math.round(pos[0] / zoom) + 0.5, Math.round(pos[1] / zoom) + 0.5);
}
function endRectSelection(mouseEvent) {
// Getting the end position
let currentPos = getCursorPosition(mouseEvent);
endX = Math.round(currentPos[0] / zoom) + 0.5;
endY = Math.round(currentPos[1] / zoom) + 0.5;
// Inverting end and start (start must always be the top left corner)
if (endX < startX) {
let tmp = endX;
endX = startX;
startX = tmp;
}
// Same for the y
if (endY < startY) {
let tmp = endY;
endY = startY;
startY = tmp;
}
// Selecting the move tool
currentTool = 'moveselection';
currentToolTemp = currentTool;
// Resetting this
isRectSelecting = false;
// Updating the cursor
updateCursor();
}
function cutSelection(mouseEvent) {
console.log("Coordinate: start x, y: " + startX + ", " + startY + " end x, y: " + endX + ", " + endY);
// Getting the selected pixels
imageDataToMove = currentLayer.context.getImageData(startX, startY, endX - startX + 1, endY - startY + 1);
currentLayer.context.clearRect(startX - 0.5, startY - 0.5, endX - startX + 1, endY - startY + 1);
// Moving those pixels from the current layer to the tmp layer
TMPLayer.context.putImageData(imageDataToMove, startX + 1, startY);
//originalDataPosition = [currentPos[0], currentPos[1]];
}
function drawRect(x, y) {
// Getting the vfx context
let vfxContext = VFXCanvas.getContext("2d");
// Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
vfxContext.lineWidth = 1;
vfxContext.strokeStyle = "black";
vfxContext.setLineDash([4]);
// Drawing the rect
vfxContext.beginPath();
vfxContext.rect(startX, startY, x - startX, y - startY);
vfxContext.stroke();
// TODO: make the rect blink from black to white in case of dark backgrounds
}
function applyChanges() {
VFXCanvas.style.zIndex = MIN_Z_INDEX;
}
// Checks whether the pointer is inside the selected area or not
function cursorInSelectedArea() {
let cursorPos = getCursorPosition(currentMouseEvent);
let x = cursorPos[0] / zoom;
let y = cursorPos[1] / zoom;
let leftX = Math.min(startX, endX);
let rightX = Math.max(startX, endX);
let topY = Math.max(startY, endY);
let bottomY = Math.min(startY, endY);
if (leftX <= x && x <= rightX) {
if (bottomY <= y && y <= topY) {
return true;
}
return false;
}
return false;
}
function moveSelection(x, y, width, height) {
// Getting the vfx context
let vfxContext = VFXCanvas.getContext("2d");
// Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
vfxContext.lineWidth = 1;
vfxContext.setLineDash([4]);
startX = Math.round(Math.round(x) - Math.round(width / 2)) + 0.5;
startY = Math.round(Math.round(y) - Math.round(height / 2)) + 0.5;
endX = startX + Math.round(width);
endY = startY + Math.round(height);
// Drawing the rect
vfxContext.beginPath();
vfxContext.rect(startX, startY, width, height);
vfxContext.stroke();
}

121
js/_rectangle.js Normal file
View File

@ -0,0 +1,121 @@
var rectangleSize = 1;
var prevRectangleSie = rectangleSize;
var emptySVG = document.getElementById("empty-button-svg");
var fullSVG = document.getElementById("full-button-svg");
var drawMode = 'empty';
var isDrawingRect = false;
let startRectX;
let startRectY;
let endRectX;
let endRectY;
function startRectDrawing(mouseEvent) {
// Putting the vfx layer on top of everything
VFXCanvas.style.zIndex = MAX_Z_INDEX;
// Updating flag
isDrawingRect = true;
// Saving the start coords of the rect
let cursorPos = getCursorPosition(mouseEvent);
startRectX = Math.round(cursorPos[0] / zoom) - 0.5;
startRectY = Math.round(cursorPos[1] / zoom) - 0.5;
drawRectangle(startRectX, startRectY);
}
function updateRectDrawing(mouseEvent) {
let pos = getCursorPosition(mouseEvent);
// Drawing the rect
drawRectangle(Math.round(pos[0] / zoom) + 0.5, Math.round(pos[1] / zoom) + 0.5);
}
function endRectDrawing(mouseEvent) {
// Getting the end position
let currentPos = getCursorPosition(mouseEvent);
let vfxContext = VFXCanvas.getContext("2d");
endRectX = Math.round(currentPos[0] / zoom) + 0.5;
endRectY = Math.round(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;
}
let hexColor = hexToRgb(currentLayer.context.fillStyle);
// Resetting this
isDrawingRect = false;
// Drawing the rect
startRectY -= 0.5;
endRectY -= 0.5;
endRectX -= 0.5;
startRectX -= 0.5;
currentLayer.context.lineWidth = rectangleSize;
currentLayer.context.fillStyle = currentGlobalColor;
line(startRectX, startRectY, endRectX, startRectY, rectangleSize);
line(endRectX, startRectY, endRectX, endRectY, rectangleSize);
line(endRectX, endRectY, startRectX, endRectY, rectangleSize);
line(startRectX, endRectY, startRectX, startRectY, rectangleSize);
if (drawMode == 'fill') {
currentLayer.context.fillRect(startRectX, startRectY, endRectX - startRectX, endRectY - startRectY);
}
// Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
}
function drawRectangle(x, y) {
// Getting the vfx context
let vfxContext = VFXCanvas.getContext("2d");
// Clearing the vfx canvas
vfxContext.clearRect(0, 0, VFXCanvas.width, VFXCanvas.height);
// Drawing the rect
vfxContext.lineWidth = rectangleSize;
vfxContext.strokeStyle = currentGlobalColor;
// Drawing the rect
vfxContext.beginPath();
if ((rectangleSize % 2 ) == 0) {
vfxContext.rect(startRectX - 0.5, startRectY - 0.5, x - startRectX, y - startRectY);
}
else {
vfxContext.rect(startRectX, startRectY, x - startRectX, y - startRectY);
}
vfxContext.setLineDash([]);
vfxContext.stroke();
}
function setRectToolSvg() {
if (drawMode == 'empty') {
emptySVG.setAttribute("display", "visible");
fullSVG.setAttribute("display", "none");
}
else {
emptySVG.setAttribute("display", "none");
fullSVG.setAttribute("display", "visible");
}
}
function applyChanges() {
VFXCanvas.style.zIndex = MIN_Z_INDEX;
}

View File

@ -32,6 +32,36 @@ on('click',"eraser-smaller-button", function(e){
updateCursor();
}, false);
// rectangle
on('click',"rectangle-button", function(){
// If the user clicks twice on the button, they change the draw mode
if (currentTool == 'rectangle') {
if (drawMode == 'empty') {
drawMode = 'fill';
setRectToolSvg();
}
else {
drawMode = 'empty';
setRectToolSvg();
}
}
else {
changeTool('rectangle');
}
}, false);
// rectangle bigger
on('click',"rectangle-bigger-button", function(){
rectangleSize++;
updateCursor();
}, false);
// rectangle smaller
on('click',"rectangle-smaller-button", function(e){
if(rectangleSize > 1) rectangleSize--;
updateCursor();
}, false);
//fill
on('click',"fill-button", function(){
changeTool('fill');
@ -69,4 +99,9 @@ on('click',"zoom-out-button", function(){
for (let i=1; i<layers.length; i++) {
layers[i].copyData(layers[0]);
}
}, false);
//rectangular selection button
on('click', "rectselect-button", function(){
changeTool('rectselect');
}, false);

View File

@ -4,14 +4,32 @@ function updateCursor () {
if (currentTool == 'pencil' || currentTool == 'resize-brush') {
canvasView.style.cursor = 'crosshair';
brushPreview.style.display = 'block';
brushPreview.style.width = brushSize * zoom + 'px';
brushPreview.style.height = brushSize * zoom + 'px';
brushPreview.style.width = pencilSize * zoom + 'px';
brushPreview.style.height = pencilSize * zoom + 'px';
} else if (currentTool == 'eraser' || currentTool == 'resize-eraser') {
canvasView.style.cursor = 'crosshair';
brushPreview.style.display = 'block';
brushPreview.style.width = eraserSize * zoom + 'px';
brushPreview.style.height = eraserSize * zoom + 'px';
} else
} else if (currentTool == 'rectangle' || currentTool == 'resize-rectangle') {
canvasView.style.cursor = 'crosshair';
brushPreview.style.display = 'block';
brushPreview.style.width = rectangleSize * zoom + 'px';
brushPreview.style.height = rectangleSize * zoom + 'px';
}
else if (currentTool == 'moveselection') {
if (cursorInSelectedArea()) {
canMoveSelection = true;
canvasView.style.cursor = 'move';
brushPreview.style.display = 'none';
}
else {
canvasView.style.cursor = 'crosshair';
}
}
else if (currentTool == 'rectselect')
canvasView.style.cursor = 'crosshair';
else
brushPreview.style.display = 'none';
if (currentTool == 'eyedropper') {

File diff suppressed because one or more lines are too long

View File

@ -13,10 +13,12 @@
//=include utilities/rgbToHsl.js
//=include utilities/hslToRgb.js
//=include libraries/cookies.js
//=include _pixelEditorUtility.js
/**init**/
//=include _consts.js
//=include _variables.js
//=include _settings.js
@ -42,7 +44,7 @@
//=include _deleteColor.js
//=include _replaceAllOfColor.js
//=include _checkerboard.js
//=include _canvas.js
//=include _layer.js
/**load file**/
@ -59,6 +61,9 @@
//=include _clickedColor.js
//=include _fileMenu.js
//=include _createButton.js
//=include _rectSelect.js
//=include _move.js
//=include _rectangle.js
/**onload**/

41
package-lock.json generated
View File

@ -1220,7 +1220,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -1238,11 +1239,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -1255,15 +1258,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -1366,7 +1372,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -1376,6 +1383,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -1388,17 +1396,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -1415,6 +1426,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -1487,7 +1499,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -1497,6 +1510,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -1572,7 +1586,8 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true
"bundled": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -1602,6 +1617,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -1619,6 +1635,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -1657,11 +1674,13 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true
"bundled": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true
"bundled": true,
"optional": true
}
}
},

View File

@ -1,4 +1,10 @@
<!DOCTYPE html>
<!--todo: credit RECTANGULAR SELECTION ICON BY https://www.flaticon.com/authors/pixel-perfect or
design an original icon (this is just a placeholder)
Must also credit this guy for the rectangle tool
Icons made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon"> www.flaticon.com</a>
-->
<html>
<head>
@ -10,7 +16,6 @@
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
{{{google-analytics}}}
{{{favicons}}}
</head>
<body oncontextmenu="return false;">
@ -34,7 +39,10 @@
<img src="/pixel-editor/pencil.png" />
<img src="/pixel-editor/zoom-in.png" />
<img src = "/pixel-editor/eraser.png"/>
<img src = "/pixel-editor/rectselect.png"/>
<img src= "/pixel-editor/rectangle.png">
</div>
<ul id="main-menu">
<li class="logo">Lospec Pixel Editor</li>
<li>
@ -70,19 +78,32 @@
<button title="Increase Brush Size" id="pencil-bigger-button" class="tools-menu-sub-button">{{svg "plus.svg" width="12" height="12"}}</button>
<button title="Decrease Brush Size" id="pencil-smaller-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
</li>
<li class = "expanded">
<button title="Eraser tool (R)" id="eraser-button">{{svg "eraser.svg" width="32" height="32"}}</button>
<button title="Increase Eraser Size" id="eraser-bigger-button" class="tools-menu-sub-button">{{svg "plus.svg" width="12" height="12"}}</button>
<button title="Decrease Eraser Size" id="eraser-smaller-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
</li>
<li class="expanded">
<button title="Rectangle Tool (U)" id="rectangle-button">{{svg "rectangle.svg" width="32" height="32" id = "empty-button-svg"}}
{{svg "fullrect.svg" width="32" height="32" id = "full-button-svg" display = "none"}}</button>
<button title="Increase Brush Size" id="rectangle-bigger-button" class="tools-menu-sub-button">{{svg "plus.svg" width="12" height="12"}}</button>
<button title="Decrease Brush Size" id="rectangle-smaller-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
</li>
<li><button title="Fill Tool (F)" id="fill-button">{{svg "fill.svg" width="32" height="32"}}</button></li>
<li><button title="Eyedropper Tool (E)" id="eyedropper-button">{{svg "eyedropper.svg" width="32" height="32"}}</button></li>
<li><button title="Pan Tool (P)" id="pan-button">{{svg "pan.svg" width="32" height="32"}}</button></li>
<li class="expanded">
<button title="Zoom Tool (Z)" id="zoom-button">{{svg "zoom.svg" width="32" height="32"}}</button>
<button title="Zoom In" id="zoom-in-button" class="tools-menu-sub-button">{{svg "plus.svg" width="12" height="12"}}</button>
<button title="Zoom Out" id="zoom-out-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
</li>
<li class = "expanded">
<button title="Eraser tool (R)" id="eraser-button">{{svg "eraser.svg" width="32" height="32"}}</button>
<button title="Increase Eraser Size" id="eraser-bigger-button" class="tools-menu-sub-button">{{svg "plus.svg" width="12" height="12"}}</button>
<button title="Decrease Eraser Size" id="eraser-smaller-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
</li>
<li><button title = "Rectangular Selection Tool (M)" id = "rectselect-button">{{svg "rectselect.svg" width = "32" height = "32"}}</button><li>
</ul>
<ul id="colors-menu">
@ -98,6 +119,8 @@
<div id="brush-preview"></div>
<div id="canvas-view">
<canvas id="vfx-canvas" class = "drawingCanvas"></canvas>
<canvas id = "tmp-canvas" class = "drawingCanvas"></canvas>
<canvas id="pixel-canvas" class = "drawingCanvas"></canvas>
<canvas id="checkerboard" class = "drawingCanvas"></canvas>
</div>