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;
|
||||
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
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) {
|
||||
|
||||
// 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;
|
||||
|
@ -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');
|
||||
|
@ -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
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
|
||||
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;
|
||||
|
@ -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];
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
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) {
|
||||
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';
|
||||
}
|
||||
|
||||
|
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();
|
||||
}, 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);
|
@ -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
@ -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
41
package-lock.json
generated
@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user