mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Merge pull request #6 from unsettledgames/master
Added rectangle tool and rectangular selection
This commit is contained in:
commit
a10453c7cb
41
_ext/svg/fullrect.svg
Normal file
41
_ext/svg/fullrect.svg
Normal 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
41
_ext/svg/rectangle.svg
Normal 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
108
_ext/svg/rectselect.svg
Normal 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 |
@ -52,6 +52,7 @@ svg {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
display:none;
|
display:none;
|
||||||
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.64);
|
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.64);
|
||||||
|
background-color:transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
#checkerboard {
|
#checkerboard {
|
||||||
@ -63,6 +64,16 @@ svg {
|
|||||||
background:transparent;
|
background:transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tmp-canvas {
|
||||||
|
z-index:3;
|
||||||
|
background:transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vfx-canvas {
|
||||||
|
z-index:-5000;
|
||||||
|
background:transparent;
|
||||||
|
}
|
||||||
|
|
||||||
#eyedropper-preview {
|
#eyedropper-preview {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 45px;
|
width: 45px;
|
||||||
@ -429,13 +440,15 @@ svg {
|
|||||||
|
|
||||||
#tools-menu li button#pencil-bigger-button,
|
#tools-menu li button#pencil-bigger-button,
|
||||||
#tools-menu li button#zoom-in-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;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tools-menu li button#pencil-smaller-button,
|
#tools-menu li button#pencil-smaller-button,
|
||||||
#tools-menu li button#zoom-out-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;
|
right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +457,9 @@ svg {
|
|||||||
#tools-menu li.selected button#zoom-in-button,
|
#tools-menu li.selected button#zoom-in-button,
|
||||||
#tools-menu li.selected button#zoom-out-button,
|
#tools-menu li.selected button#zoom-out-button,
|
||||||
#tools-menu li.selected button#eraser-bigger-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;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
images/layout.png
Normal file
BIN
images/layout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
images/rectangle.png
Normal file
BIN
images/rectangle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
images/rectselect.png
Normal file
BIN
images/rectselect.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
@ -1,5 +1,8 @@
|
|||||||
function changeTool (selectedTool) {
|
function changeTool (selectedTool) {
|
||||||
|
// Ending any selection in progress
|
||||||
|
if (currentTool.includes("select") && !selectedTool.includes("select") && !selectionCanceled) {
|
||||||
|
endSelection();
|
||||||
|
}
|
||||||
//set tool and temp tje tje tpp;
|
//set tool and temp tje tje tpp;
|
||||||
currentTool = selectedTool;
|
currentTool = selectedTool;
|
||||||
currentToolTemp = selectedTool;
|
currentToolTemp = selectedTool;
|
||||||
|
@ -10,6 +10,7 @@ function clickedColor (e){
|
|||||||
|
|
||||||
//set current color
|
//set current color
|
||||||
currentLayer.context.fillStyle = this.style.backgroundColor;
|
currentLayer.context.fillStyle = this.style.backgroundColor;
|
||||||
|
currentGlobalColor = this.style.backgroundColor;
|
||||||
|
|
||||||
//make color selected
|
//make color selected
|
||||||
e.target.parentElement.classList.add('selected');
|
e.target.parentElement.classList.add('selected');
|
||||||
|
@ -28,9 +28,6 @@ function colorChanged(e) {
|
|||||||
var newColor = hexToRgb(e.target.value);
|
var newColor = hexToRgb(e.target.value);
|
||||||
var oldColor = e.target.oldColor;
|
var oldColor = e.target.oldColor;
|
||||||
|
|
||||||
console.log('newColor',newColor)
|
|
||||||
console.log('oldColor',oldColor)
|
|
||||||
|
|
||||||
//save undo state
|
//save undo state
|
||||||
//saveHistoryState({type: 'colorchange', newColor: e.target.value, oldColor: rgbToHex(oldColor), canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
|
//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));
|
new HistoryStateEditColor(e.target.value.toLowerCase(), rgbToHex(oldColor));
|
||||||
@ -50,15 +47,14 @@ function colorChanged(e) {
|
|||||||
|
|
||||||
//loop through all colors in palette
|
//loop through all colors in palette
|
||||||
for (var i = 0; i < colors.length; i++) {
|
for (var i = 0; i < colors.length; i++) {
|
||||||
console.log('%c'+newColorHex +' '+ colors[i].jscolor.toString(), colorCheckingStyle)
|
|
||||||
|
|
||||||
//if generated color matches this color
|
//if generated color matches this color
|
||||||
if (newColorHex == colors[i].jscolor.toString()) {
|
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 the color isnt the one that has the picker currently open
|
||||||
if (!colors[i].parentElement.classList.contains('jscolor-active')) {
|
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
|
//show the duplicate color warning
|
||||||
duplicateColorWarning.style.visibility = 'visible';
|
duplicateColorWarning.style.visibility = 'visible';
|
||||||
@ -83,13 +79,12 @@ function colorChanged(e) {
|
|||||||
|
|
||||||
//set new old color to changed color
|
//set new old color to changed color
|
||||||
e.target.oldColor = newColor;
|
e.target.oldColor = newColor;
|
||||||
|
|
||||||
console.log(e.target.colorElement);
|
|
||||||
|
|
||||||
//if this is the current color, update the drawing color
|
//if this is the current color, update the drawing color
|
||||||
if (e.target.colorElement.parentElement.classList.contains('selected')) {
|
if (e.target.colorElement.parentElement.classList.contains('selected')) {
|
||||||
console.log('this color is the current color');
|
//console.log('this color is the current color');
|
||||||
context.fillStyle = '#'+ rgbToHex(newColor.r,newColor.g,newColor.b);
|
context.fillStyle = currentColor;
|
||||||
}
|
}
|
||||||
/* this is wrong and bad
|
/* this is wrong and bad
|
||||||
if (settings.switchToChangedColor) {
|
if (settings.switchToChangedColor) {
|
||||||
|
2
js/_consts.js
Normal file
2
js/_consts.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
const MIN_Z_INDEX = -5000;
|
||||||
|
const MAX_Z_INDEX = 5000;
|
@ -1,5 +1,5 @@
|
|||||||
//draw a line between two points on canvas
|
//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 dx = Math.abs(x1-x0);
|
||||||
var dy = Math.abs(y1-y0);
|
var dy = Math.abs(y1-y0);
|
||||||
@ -10,7 +10,7 @@ function line(x0,y0,x1,y1) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
//set pixel
|
//set pixel
|
||||||
// If the current tool is the brush
|
// If the current tool is the brush
|
||||||
if (currentTool == 'pencil') {
|
if (currentTool == 'pencil' || currentTool == 'rectangle') {
|
||||||
// I fill the rect
|
// I fill the rect
|
||||||
currentLayer.context.fillRect(x0-Math.floor(brushSize/2), y0-Math.floor(brushSize/2), brushSize, brushSize);
|
currentLayer.context.fillRect(x0-Math.floor(brushSize/2), y0-Math.floor(brushSize/2), brushSize, brushSize);
|
||||||
} else if (currentTool == 'eraser') {
|
} 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);
|
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 we've reached the end goal, exit the loop
|
||||||
if ((x0==x1) && (y0==y1)) break;
|
if ((x0==x1) && (y0==y1)) break;
|
||||||
var e2 = 2*err;
|
var e2 = 2*err;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
function getCursorPosition(e) {
|
function getCursorPosition(e) {
|
||||||
var x;
|
var x;
|
||||||
var y;
|
var y;
|
||||||
|
|
||||||
if (e.pageX != undefined && e.pageY != undefined) {
|
if (e.pageX != undefined && e.pageY != undefined) {
|
||||||
x = e.pageX;
|
x = e.pageX;
|
||||||
y = e.pageY;
|
y = e.pageY;
|
||||||
@ -14,5 +15,29 @@ function getCursorPosition(e) {
|
|||||||
x -= canvas.offsetLeft;
|
x -= canvas.offsetLeft;
|
||||||
y -= canvas.offsetTop;
|
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];
|
return [x,y];
|
||||||
}
|
}
|
@ -1,65 +1,86 @@
|
|||||||
var spacePressed = false;
|
var spacePressed = false;
|
||||||
|
|
||||||
function KeyPress(e) {
|
function KeyPress(e) {
|
||||||
var keyboardEvent = window.event? event : e;
|
var keyboardEvent = window.event? event : e;
|
||||||
|
|
||||||
//if the user is typing in an input field, ignore these hotkeys
|
//if the user is typing in an input field, ignore these hotkeys
|
||||||
if (document.activeElement.tagName == 'INPUT') return;
|
if (document.activeElement.tagName == 'INPUT') return;
|
||||||
|
|
||||||
//if no document has been created yet,
|
//if no document has been created yet,
|
||||||
//orthere is a dialog box open
|
//orthere is a dialog box open
|
||||||
//ignore hotkeys
|
//ignore hotkeys
|
||||||
if (!documentCreated || dialogueOpen) return;
|
if (!documentCreated || dialogueOpen) return;
|
||||||
|
|
||||||
//
|
//
|
||||||
switch (keyboardEvent.keyCode) {
|
if (e.key === "Escape") {
|
||||||
//pencil tool - 1, b
|
if (!selectionCanceled) {
|
||||||
case 49: case 66:
|
endSelection();
|
||||||
changeTool('pencil');
|
changeTool('pencil');
|
||||||
break;
|
}
|
||||||
//fill tool - 2, f
|
}
|
||||||
case 50: case 70:
|
else {
|
||||||
changeTool('fill');
|
switch (keyboardEvent.keyCode) {
|
||||||
break;
|
//pencil tool - 1, b
|
||||||
//eyedropper - 3, e
|
case 49: case 66:
|
||||||
case 51: case 69:
|
changeTool('pencil');
|
||||||
changeTool('eyedropper');
|
break;
|
||||||
break;
|
//fill tool - 2, f
|
||||||
//pan - 4, p, m
|
case 50: case 70:
|
||||||
case 52: case 80: case 77:
|
changeTool('fill');
|
||||||
changeTool('pan');
|
break;
|
||||||
break;
|
//eyedropper - 3, e
|
||||||
//zoom - 5
|
case 51: case 69:
|
||||||
case 53:
|
changeTool('eyedropper');
|
||||||
changeTool('zoom');
|
break;
|
||||||
break;
|
//pan - 4, p,
|
||||||
// eraser -6, r
|
case 52: case 80:
|
||||||
case 54: case 82:
|
changeTool('pan');
|
||||||
console.log("Pressed r");
|
break;
|
||||||
changeTool('eraser');
|
//zoom - 5
|
||||||
break;
|
case 53:
|
||||||
//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
|
|
||||||
changeTool('zoom');
|
changeTool('zoom');
|
||||||
break;
|
break;
|
||||||
//redo - ctrl y
|
// eraser -6, r
|
||||||
case 89:
|
case 54: case 82:
|
||||||
if (keyboardEvent.ctrlKey)
|
console.log("Pressed r");
|
||||||
redo();
|
changeTool('eraser');
|
||||||
break;
|
break;
|
||||||
case 32:
|
// Rectangular selection
|
||||||
spacePressed=true;
|
case 77: case 109:
|
||||||
break;
|
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;
|
document.onkeydown = KeyPress;
|
||||||
|
@ -1,48 +1,61 @@
|
|||||||
/** Handler class for a single canvas (a single layer)
|
/** TODO LIST FOR LAYERS
|
||||||
*
|
- move the tmp layer so that it's always right below the active layer
|
||||||
* @param width Canvas width
|
- when the move tool is selected (to move a selection), the tmp layer must be put right above the
|
||||||
* @param height Canvas height
|
active layer to show a preview
|
||||||
* @param canvas HTML canvas element
|
- 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
|
||||||
function Canvas(width, height, canvas) {
|
the first one in order of z-index
|
||||||
this.canvasSize = [width, height],
|
*/
|
||||||
this.canvas = canvas,
|
|
||||||
this.context = this.canvas.getContext("2d"),
|
|
||||||
// Initializes the canvas
|
/** Handler class for a single canvas (a single layer)
|
||||||
this.initialize = function() {
|
*
|
||||||
var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75);
|
* @param width Canvas width
|
||||||
var maxVerticalZoom = Math.floor(window.innerHeight/this.canvasSize[1]*0.75);
|
* @param height Canvas height
|
||||||
|
* @param canvas HTML canvas element
|
||||||
zoom = Math.min(maxHorizontalZoom,maxVerticalZoom);
|
*/
|
||||||
if (zoom < 1) zoom = 1;
|
function Layer(width, height, canvas) {
|
||||||
|
this.canvasSize = [width, height],
|
||||||
//resize canvas
|
this.canvas = canvas,
|
||||||
this.canvas.width = this.canvasSize[0];
|
this.context = this.canvas.getContext("2d"),
|
||||||
this.canvas.height = this.canvasSize[1];
|
// Initializes the canvas
|
||||||
this.canvas.style.width = (this.canvas.width*zoom)+'px';
|
this.initialize = function() {
|
||||||
this.canvas.style.height = (this.canvas.height*zoom)+'px';
|
var maxHorizontalZoom = Math.floor(window.innerWidth/this.canvasSize[0]*0.75);
|
||||||
|
var maxVerticalZoom = Math.floor(window.innerHeight/this.canvasSize[1]*0.75);
|
||||||
//unhide canvas
|
|
||||||
this.canvas.style.display = 'block';
|
zoom = Math.min(maxHorizontalZoom,maxVerticalZoom);
|
||||||
|
if (zoom < 1) zoom = 1;
|
||||||
//center canvas in window
|
|
||||||
this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px';
|
//resize canvas
|
||||||
this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px';
|
this.canvas.width = this.canvasSize[0];
|
||||||
},
|
this.canvas.height = this.canvasSize[1];
|
||||||
// Resizes canvas
|
this.canvas.style.width = (this.canvas.width*zoom)+'px';
|
||||||
this.resize = function() {
|
this.canvas.style.height = (this.canvas.height*zoom)+'px';
|
||||||
let newWidth = (this.canvas.width * zoom) + 'px';
|
|
||||||
let newHeight = (this.canvas.height *zoom)+ 'px';
|
//unhide canvas
|
||||||
|
this.canvas.style.display = 'block';
|
||||||
this.canvas.style.width = newWidth;
|
|
||||||
this.canvas.style.height = newHeight;
|
//center canvas in window
|
||||||
},
|
this.canvas.style.left = 64+canvasView.clientWidth/2-(this.canvasSize[0]*zoom/2)+'px';
|
||||||
// Copies the otherCanvas' position and size
|
this.canvas.style.top = 48+canvasView.clientHeight/2-(this.canvasSize[1]*zoom/2)+'px';
|
||||||
this.copyData = function(otherCanvas) {
|
|
||||||
this.canvas.style.width = otherCanvas.canvas.style.width;
|
this.context.imageSmoothingEnabled = false;
|
||||||
this.canvas.style.height = otherCanvas.canvas.style.height;
|
this.context.mozImageSmoothingEnabled = false;
|
||||||
|
},
|
||||||
this.canvas.style.left = otherCanvas.canvas.style.left;
|
// Resizes canvas
|
||||||
this.canvas.style.top = otherCanvas.canvas.style.top;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,12 @@
|
|||||||
|
var currentMouseEvent;
|
||||||
|
// TODO: replace every position calculation with lastMousePos
|
||||||
|
var lastMousePos;
|
||||||
|
|
||||||
//mousedown - start drawing
|
//mousedown - start drawing
|
||||||
window.addEventListener("mousedown", function (mouseEvent) {
|
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 no document has been created yet, or this is a dialog open
|
||||||
if (!documentCreated || dialogueOpen) return;
|
if (!documentCreated || dialogueOpen) return;
|
||||||
@ -10,31 +16,43 @@ window.addEventListener("mousedown", function (mouseEvent) {
|
|||||||
lastPos = getCursorPosition(mouseEvent);
|
lastPos = getCursorPosition(mouseEvent);
|
||||||
|
|
||||||
dragging = true;
|
dragging = true;
|
||||||
//left or right click
|
//left or right click ?
|
||||||
if (mouseEvent.which == 1) {
|
if (mouseEvent.which == 1) {
|
||||||
|
|
||||||
if (spacePressed)
|
if (spacePressed)
|
||||||
currentTool = 'pan';
|
currentTool = 'pan';
|
||||||
else if (mouseEvent.altKey)
|
else if (mouseEvent.altKey)
|
||||||
currentTool = 'eyedropper';
|
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();
|
new HistoryStateEditCanvas();
|
||||||
|
else if (currentTool == 'moveselection') {
|
||||||
|
if (!cursorInSelectedArea()) {
|
||||||
|
changeTool('pencil');
|
||||||
|
canDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
//saveHistoryState({type: 'canvas', canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
|
//saveHistoryState({type: 'canvas', canvas: context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
|
||||||
|
|
||||||
updateCursor();
|
updateCursor();
|
||||||
|
|
||||||
draw(mouseEvent);
|
if (canDraw) {
|
||||||
|
draw(mouseEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (currentTool == 'pencil' && mouseEvent.which == 3) {
|
else if (currentTool == 'pencil' && mouseEvent.which == 3) {
|
||||||
currentTool = 'resize-brush';
|
currentTool = 'resize-brush';
|
||||||
prevBrushSize = brushSize;
|
prevBrushSize = pencilSize;
|
||||||
}
|
}
|
||||||
else if (currentTool == 'eraser' && mouseEvent.which == 3) {
|
else if (currentTool == 'eraser' && mouseEvent.which == 3) {
|
||||||
currentTool = 'resize-eraser';
|
currentTool = 'resize-eraser';
|
||||||
prevEraserSize = eraserSize;
|
prevEraserSize = eraserSize;
|
||||||
}
|
}
|
||||||
|
else if (currentTool == 'rectangle' && mouseEvent.which == 3) {
|
||||||
if (currentTool == 'eyedropper' && mouseEvent.target == currentLayer.canvas)
|
currentTool = 'resize-rectangle';
|
||||||
|
prevRectangleSize = rectangleSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTool == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas')
|
||||||
eyedropperPreview.style.display = 'block';
|
eyedropperPreview.style.display = 'block';
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -44,47 +62,45 @@ window.addEventListener("mousedown", function (mouseEvent) {
|
|||||||
|
|
||||||
//mouseup - end drawing
|
//mouseup - end drawing
|
||||||
window.addEventListener("mouseup", function (mouseEvent) {
|
window.addEventListener("mouseup", function (mouseEvent) {
|
||||||
|
// Saving the event in case something else needs it
|
||||||
|
currentMouseEvent = mouseEvent;
|
||||||
|
|
||||||
closeMenu();
|
closeMenu();
|
||||||
|
|
||||||
if (!documentCreated || dialogueOpen) return;
|
if (!documentCreated || dialogueOpen) return;
|
||||||
|
|
||||||
if (currentTool == 'eyedropper' && mouseEvent.target == currentLayer.canvas) {
|
if (currentTool == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas') {
|
||||||
var cursorLocation = getCursorPosition(mouseEvent);
|
var cursorLocation = getCursorPosition(mouseEvent);
|
||||||
var selectedColor = context.getImageData(Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom),1,1);
|
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]);
|
var newColor = rgbToHex(selectedColor.data[0],selectedColor.data[1],selectedColor.data[2]);
|
||||||
|
|
||||||
console.log(newColor);
|
currentGlobalColor = "#" + newColor;
|
||||||
|
|
||||||
var colors = document.getElementsByClassName('color-button');
|
var colors = document.getElementsByClassName('color-button');
|
||||||
for (var i = 0; i < colors.length; i++) {
|
for (var i = 0; i < colors.length; i++) {
|
||||||
console.log(colors[i].jscolor.toString());
|
console.log(colors[i].jscolor.toString());
|
||||||
|
|
||||||
//if picked color matches this color
|
//if picked color matches this color
|
||||||
if (newColor == colors[i].jscolor.toString()) {
|
if (newColor == colors[i].jscolor.toString()) {
|
||||||
console.log('color found');
|
console.log('color found');
|
||||||
|
|
||||||
//remove current color selection
|
//remove current color selection
|
||||||
var selectedColor = document.querySelector("#colors-menu li.selected")
|
var selectedColor = document.querySelector("#colors-menu li.selected")
|
||||||
if (selectedColor) selectedColor.classList.remove("selected");
|
if (selectedColor) selectedColor.classList.remove("selected");
|
||||||
|
|
||||||
//set current color
|
//set current color
|
||||||
context.fillStyle = '#'+newColor;
|
context.fillStyle = '#'+newColor;
|
||||||
|
|
||||||
//make color selected
|
//make color selected
|
||||||
colors[i].parentElement.classList.add('selected');
|
colors[i].parentElement.classList.add('selected');
|
||||||
|
|
||||||
//hide eyedropper
|
//hide eyedropper
|
||||||
eyedropperPreview.style.display = 'none';
|
eyedropperPreview.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (currentTool == 'fill' && mouseEvent.target == currentLayer.canvas) {
|
else if (currentTool == 'fill' && mouseEvent.target.className == 'drawingCanvas') {
|
||||||
console.log('filling')
|
console.log('filling')
|
||||||
//if you clicked on anything but the canvas, do nothing
|
|
||||||
if (!mouseEvent.target == currentLayer.canvas) return;
|
|
||||||
|
|
||||||
//get cursor postion
|
//get cursor postion
|
||||||
var cursorLocation = getCursorPosition(mouseEvent);
|
var cursorLocation = getCursorPosition(mouseEvent);
|
||||||
@ -96,7 +112,7 @@ window.addEventListener("mouseup", function (mouseEvent) {
|
|||||||
//fill starting at the location
|
//fill starting at the location
|
||||||
fill(cursorLocation);
|
fill(cursorLocation);
|
||||||
}
|
}
|
||||||
else if (currentTool == 'zoom' && mouseEvent.target == canvasView) {
|
else if (currentTool == 'zoom' && mouseEvent.target.className == 'drawingCanvas') {
|
||||||
let mode;
|
let mode;
|
||||||
if (mouseEvent.which == 1){
|
if (mouseEvent.which == 1){
|
||||||
mode = "in";
|
mode = "in";
|
||||||
@ -111,6 +127,12 @@ window.addEventListener("mouseup", function (mouseEvent) {
|
|||||||
layers[i].copyData(layers[0]);
|
layers[i].copyData(layers[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (currentTool == 'rectselect' && isRectSelecting) {
|
||||||
|
endRectSelection(mouseEvent);
|
||||||
|
}
|
||||||
|
else if (currentTool == 'rectangle') {
|
||||||
|
endRectDrawing(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
dragging = false;
|
dragging = false;
|
||||||
currentTool = currentToolTemp;
|
currentTool = currentToolTemp;
|
||||||
@ -121,10 +143,16 @@ window.addEventListener("mouseup", function (mouseEvent) {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
|
||||||
|
// OPTIMIZABLE: redundant || mouseEvent.target.className in currentTool ifs
|
||||||
|
|
||||||
//mouse is moving on canvas
|
//mouse is moving on canvas
|
||||||
window.addEventListener("mousemove", draw, false);
|
window.addEventListener("mousemove", draw, false);
|
||||||
function draw (mouseEvent) {
|
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 a document hasnt yet been created, exit this function
|
||||||
if (!documentCreated || dialogueOpen) return;
|
if (!documentCreated || dialogueOpen) return;
|
||||||
@ -133,21 +161,20 @@ function draw (mouseEvent) {
|
|||||||
eyedropperPreview.style.display = 'none';
|
eyedropperPreview.style.display = 'none';
|
||||||
|
|
||||||
if (currentTool == 'pencil') {
|
if (currentTool == 'pencil') {
|
||||||
|
|
||||||
//move the brush preview
|
//move the brush preview
|
||||||
brushPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - brushSize * zoom / 2 + 'px';
|
brushPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - pencilSize * zoom / 2 + 'px';
|
||||||
brushPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - brushSize * zoom / 2 + 'px';
|
brushPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - pencilSize * zoom / 2 + 'px';
|
||||||
|
|
||||||
//hide brush preview outside of canvas / canvas view
|
//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';
|
brushPreview.style.visibility = 'visible';
|
||||||
else
|
else
|
||||||
brushPreview.style.visibility = 'hidden';
|
brushPreview.style.visibility = 'hidden';
|
||||||
|
|
||||||
//draw line to current pixel
|
//draw line to current pixel
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView) {
|
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));
|
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom), pencilSize);
|
||||||
lastPos = cursorLocation;
|
lastPos = cursorLocation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,19 +195,38 @@ function draw (mouseEvent) {
|
|||||||
brushPreview.style.top = cursorLocation[1] + canvas.offsetTop - eraserSize * zoom / 2 + 'px';
|
brushPreview.style.top = cursorLocation[1] + canvas.offsetTop - eraserSize * zoom / 2 + 'px';
|
||||||
|
|
||||||
//hide brush preview outside of canvas / canvas view
|
//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';
|
brushPreview.style.visibility = 'visible';
|
||||||
else
|
else
|
||||||
brushPreview.style.visibility = 'hidden';
|
brushPreview.style.visibility = 'hidden';
|
||||||
|
|
||||||
//draw line to current pixel
|
//draw line to current pixel
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
if (mouseEvent.target == currentLayer.canvas || mouseEvent.target == canvasView) {
|
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));
|
line(Math.floor(lastPos[0]/zoom),Math.floor(lastPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom), eraserSize);
|
||||||
lastPos = cursorLocation;
|
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) {
|
else if (currentTool == 'pan' && dragging) {
|
||||||
// Setting first layer position
|
// Setting first layer position
|
||||||
setCanvasOffset(layers[0].canvas, layers[0].canvas.offsetLeft + (cursorLocation[0] - lastPos[0]), layers[0].canvas.offsetTop + (cursorLocation[1] - lastPos[1]));
|
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]);
|
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;
|
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.borderColor = '#'+rgbToHex(selectedColor[0],selectedColor[1],selectedColor[2]);
|
||||||
eyedropperPreview.style.display = 'block';
|
eyedropperPreview.style.display = 'block';
|
||||||
|
|
||||||
@ -212,11 +259,11 @@ function draw (mouseEvent) {
|
|||||||
var newBrushSize = prevBrushSize + brushSizeChange;
|
var newBrushSize = prevBrushSize + brushSizeChange;
|
||||||
|
|
||||||
//set the brush to the new size as long as its bigger than 1
|
//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
|
//fix offset so the cursor stays centered
|
||||||
brushPreview.style.left = lastPos[0] + currentLayer.canvas.offsetLeft - brushSize * zoom / 2 + 'px';
|
brushPreview.style.left = lastPos[0] + currentLayer.canvas.offsetLeft - pencilSize * zoom / 2 + 'px';
|
||||||
brushPreview.style.top = lastPos[1] + currentLayer.canvas.offsetTop - brushSize * zoom / 2 + 'px';
|
brushPreview.style.top = lastPos[1] + currentLayer.canvas.offsetTop - pencilSize * zoom / 2 + 'px';
|
||||||
|
|
||||||
updateCursor();
|
updateCursor();
|
||||||
}
|
}
|
||||||
@ -237,6 +284,45 @@ function draw (mouseEvent) {
|
|||||||
|
|
||||||
updateCursor();
|
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
|
//mousewheel scrroll
|
||||||
|
72
js/_move.js
Normal file
72
js/_move.js
Normal 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;
|
||||||
|
}
|
@ -1,16 +1,27 @@
|
|||||||
|
|
||||||
function newPixel (width, height, palette) {
|
function newPixel (width, height, palette) {
|
||||||
currentLayer = new Canvas(width, height, canvas);
|
// Setting the current layer
|
||||||
|
currentLayer = new Layer(width, height, canvas);
|
||||||
currentLayer.initialize();
|
currentLayer.initialize();
|
||||||
|
|
||||||
checkerBoard = new Canvas(width, height, checkerBoardCanvas);
|
// Adding the checkerboard behind it
|
||||||
|
checkerBoard = new Layer(width, height, checkerBoardCanvas);
|
||||||
checkerBoard.initialize();
|
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;
|
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(currentLayer);
|
||||||
layers.push(checkerBoard);
|
layers.push(checkerBoard);
|
||||||
|
|
||||||
//remove current palette
|
//remove current palette
|
||||||
colors = document.getElementsByClassName('color-button');
|
colors = document.getElementsByClassName('color-button');
|
||||||
while (colors.length > 0) {
|
while (colors.length > 0) {
|
||||||
@ -55,6 +66,7 @@ function newPixel (width, height, palette) {
|
|||||||
|
|
||||||
//set current drawing color as foreground color
|
//set current drawing color as foreground color
|
||||||
currentLayer.context.fillStyle = '#'+defaultForegroundColor;
|
currentLayer.context.fillStyle = '#'+defaultForegroundColor;
|
||||||
|
currentGlobalColor = '#' + defaultForegroundColor;
|
||||||
selectedPalette = 'none';
|
selectedPalette = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
js/_pixelEditorUtility.js
Normal file
7
js/_pixelEditorUtility.js
Normal 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
151
js/_rectSelect.js
Normal 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
121
js/_rectangle.js
Normal 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;
|
||||||
|
}
|
@ -32,6 +32,36 @@ on('click',"eraser-smaller-button", function(e){
|
|||||||
updateCursor();
|
updateCursor();
|
||||||
}, false);
|
}, 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
|
//fill
|
||||||
on('click',"fill-button", function(){
|
on('click',"fill-button", function(){
|
||||||
changeTool('fill');
|
changeTool('fill');
|
||||||
@ -69,4 +99,9 @@ on('click',"zoom-out-button", function(){
|
|||||||
for (let i=1; i<layers.length; i++) {
|
for (let i=1; i<layers.length; i++) {
|
||||||
layers[i].copyData(layers[0]);
|
layers[i].copyData(layers[0]);
|
||||||
}
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
//rectangular selection button
|
||||||
|
on('click', "rectselect-button", function(){
|
||||||
|
changeTool('rectselect');
|
||||||
}, false);
|
}, false);
|
@ -4,14 +4,32 @@ function updateCursor () {
|
|||||||
if (currentTool == 'pencil' || currentTool == 'resize-brush') {
|
if (currentTool == 'pencil' || currentTool == 'resize-brush') {
|
||||||
canvasView.style.cursor = 'crosshair';
|
canvasView.style.cursor = 'crosshair';
|
||||||
brushPreview.style.display = 'block';
|
brushPreview.style.display = 'block';
|
||||||
brushPreview.style.width = brushSize * zoom + 'px';
|
brushPreview.style.width = pencilSize * zoom + 'px';
|
||||||
brushPreview.style.height = brushSize * zoom + 'px';
|
brushPreview.style.height = pencilSize * zoom + 'px';
|
||||||
} else if (currentTool == 'eraser' || currentTool == 'resize-eraser') {
|
} else if (currentTool == 'eraser' || currentTool == 'resize-eraser') {
|
||||||
canvasView.style.cursor = 'crosshair';
|
canvasView.style.cursor = 'crosshair';
|
||||||
brushPreview.style.display = 'block';
|
brushPreview.style.display = 'block';
|
||||||
brushPreview.style.width = eraserSize * zoom + 'px';
|
brushPreview.style.width = eraserSize * zoom + 'px';
|
||||||
brushPreview.style.height = 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';
|
brushPreview.style.display = 'none';
|
||||||
|
|
||||||
if (currentTool == 'eyedropper') {
|
if (currentTool == 'eyedropper') {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -13,10 +13,12 @@
|
|||||||
//=include utilities/rgbToHsl.js
|
//=include utilities/rgbToHsl.js
|
||||||
//=include utilities/hslToRgb.js
|
//=include utilities/hslToRgb.js
|
||||||
//=include libraries/cookies.js
|
//=include libraries/cookies.js
|
||||||
|
//=include _pixelEditorUtility.js
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**init**/
|
/**init**/
|
||||||
|
//=include _consts.js
|
||||||
//=include _variables.js
|
//=include _variables.js
|
||||||
//=include _settings.js
|
//=include _settings.js
|
||||||
|
|
||||||
@ -42,7 +44,7 @@
|
|||||||
//=include _deleteColor.js
|
//=include _deleteColor.js
|
||||||
//=include _replaceAllOfColor.js
|
//=include _replaceAllOfColor.js
|
||||||
//=include _checkerboard.js
|
//=include _checkerboard.js
|
||||||
//=include _canvas.js
|
//=include _layer.js
|
||||||
|
|
||||||
|
|
||||||
/**load file**/
|
/**load file**/
|
||||||
@ -59,6 +61,9 @@
|
|||||||
//=include _clickedColor.js
|
//=include _clickedColor.js
|
||||||
//=include _fileMenu.js
|
//=include _fileMenu.js
|
||||||
//=include _createButton.js
|
//=include _createButton.js
|
||||||
|
//=include _rectSelect.js
|
||||||
|
//=include _move.js
|
||||||
|
//=include _rectangle.js
|
||||||
|
|
||||||
|
|
||||||
/**onload**/
|
/**onload**/
|
||||||
|
41
package-lock.json
generated
41
package-lock.json
generated
@ -1220,7 +1220,8 @@
|
|||||||
},
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@ -1238,11 +1239,13 @@
|
|||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@ -1255,15 +1258,18 @@
|
|||||||
},
|
},
|
||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -1366,7 +1372,8 @@
|
|||||||
},
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@ -1376,6 +1383,7 @@
|
|||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -1388,17 +1396,20 @@
|
|||||||
"minimatch": {
|
"minimatch": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@ -1415,6 +1426,7 @@
|
|||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@ -1487,7 +1499,8 @@
|
|||||||
},
|
},
|
||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@ -1497,6 +1510,7 @@
|
|||||||
"once": {
|
"once": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@ -1572,7 +1586,8 @@
|
|||||||
},
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
@ -1602,6 +1617,7 @@
|
|||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@ -1619,6 +1635,7 @@
|
|||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
@ -1657,11 +1674,13 @@
|
|||||||
},
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true
|
"bundled": true,
|
||||||
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
<!DOCTYPE html>
|
<!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>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
@ -10,7 +16,6 @@
|
|||||||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
||||||
{{{google-analytics}}}
|
{{{google-analytics}}}
|
||||||
{{{favicons}}}
|
{{{favicons}}}
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body oncontextmenu="return false;">
|
<body oncontextmenu="return false;">
|
||||||
@ -34,7 +39,10 @@
|
|||||||
<img src="/pixel-editor/pencil.png" />
|
<img src="/pixel-editor/pencil.png" />
|
||||||
<img src="/pixel-editor/zoom-in.png" />
|
<img src="/pixel-editor/zoom-in.png" />
|
||||||
<img src = "/pixel-editor/eraser.png"/>
|
<img src = "/pixel-editor/eraser.png"/>
|
||||||
|
<img src = "/pixel-editor/rectselect.png"/>
|
||||||
|
<img src= "/pixel-editor/rectangle.png">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul id="main-menu">
|
<ul id="main-menu">
|
||||||
<li class="logo">Lospec Pixel Editor</li>
|
<li class="logo">Lospec Pixel Editor</li>
|
||||||
<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="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>
|
<button title="Decrease Brush Size" id="pencil-smaller-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
|
||||||
</li>
|
</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="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="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><button title="Pan Tool (P)" id="pan-button">{{svg "pan.svg" width="32" height="32"}}</button></li>
|
||||||
<li class="expanded">
|
<li class="expanded">
|
||||||
<button title="Zoom Tool (Z)" id="zoom-button">{{svg "zoom.svg" width="32" height="32"}}</button>
|
<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 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>
|
<button title="Zoom Out" id="zoom-out-button" class="tools-menu-sub-button">{{svg "minus.svg" width="12" height="12"}}</button>
|
||||||
</li>
|
</li>
|
||||||
<li class = "expanded">
|
|
||||||
<button title="Eraser tool (R)" id="eraser-button">{{svg "eraser.svg" width="32" height="32"}}</button>
|
<li><button title = "Rectangular Selection Tool (M)" id = "rectselect-button">{{svg "rectselect.svg" width = "32" height = "32"}}</button><li>
|
||||||
<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>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul id="colors-menu">
|
<ul id="colors-menu">
|
||||||
@ -98,6 +119,8 @@
|
|||||||
<div id="brush-preview"></div>
|
<div id="brush-preview"></div>
|
||||||
|
|
||||||
<div id="canvas-view">
|
<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="pixel-canvas" class = "drawingCanvas"></canvas>
|
||||||
<canvas id="checkerboard" class = "drawingCanvas"></canvas>
|
<canvas id="checkerboard" class = "drawingCanvas"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user