mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Added back selection pasting and end of selection
This commit is contained in:
parent
06f534e38e
commit
afff386e5f
@ -1,3 +1,10 @@
|
|||||||
|
/** TODO:
|
||||||
|
* - Clear cut selection
|
||||||
|
* - Clear copy selection
|
||||||
|
* - Clear paste selection
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
class MoveSelectionTool extends DrawingTool {
|
class MoveSelectionTool extends DrawingTool {
|
||||||
currSelection = undefined;
|
currSelection = undefined;
|
||||||
selectionTool = undefined;
|
selectionTool = undefined;
|
||||||
@ -58,29 +65,35 @@ class MoveSelectionTool extends DrawingTool {
|
|||||||
|
|
||||||
onStart(mousePos, mouseTarget) {
|
onStart(mousePos, mouseTarget) {
|
||||||
super.onStart(mousePos, mouseTarget);
|
super.onStart(mousePos, mouseTarget);
|
||||||
|
|
||||||
if (!this.selectionTool.cursorInSelectedArea(mousePos) &&
|
|
||||||
!Util.isChildOfByClass(mouseTarget, "editor-top-menu")) {
|
|
||||||
this.endSelection();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrag(mousePos) {
|
onDrag(mousePos) {
|
||||||
super.onDrag(mousePos);
|
super.onDrag(mousePos);
|
||||||
|
|
||||||
// TODO: add (or subtract?) vector (boundingBoxCenter - canvasCenter);
|
// TODO: add (or subtract?) vector (boundingBoxCenter - canvasCenter);
|
||||||
this.selectionTool.moveOffset = [Math.floor(mousePos[0] / currFile.zoom - currFile.canvasSize[0] / 2),
|
this.selectionTool.moveOffset =
|
||||||
Math.floor(mousePos[1] / currFile.zoom - currFile.canvasSize[1] / 2)];
|
[Math.floor(mousePos[0] / currFile.zoom - currFile.canvasSize[0] / 2 - (this.selectionTool.boundingBoxCenter[0] - currFile.canvasSize[0]/2)),
|
||||||
|
Math.floor(mousePos[1] / currFile.zoom - currFile.canvasSize[1] / 2- (this.selectionTool.boundingBoxCenter[1] - currFile.canvasSize[1]/2))];
|
||||||
// clear the entire tmp layer
|
// clear the entire tmp layer
|
||||||
currFile.TMPLayer.context.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
currFile.TMPLayer.context.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
||||||
// put the image data on the tmp layer with offset
|
// put the image data on the tmp layer with offset
|
||||||
currFile.TMPLayer.context.putImageData(this.currSelection,
|
currFile.TMPLayer.context.putImageData(this.currSelection,
|
||||||
this.selectionTool.moveOffset[0], this.selectionTool.moveOffset[1]);
|
this.selectionTool.moveOffset[0], this.selectionTool.moveOffset[1]);
|
||||||
this.selectionTool.drawSelectedArea();
|
|
||||||
|
// Draw the selection area and outline
|
||||||
|
this.selectionTool.drawOutline();
|
||||||
|
this.selectionTool.drawSelectedArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
onEnd(mousePos) {
|
onEnd(mousePos, mouseTarget) {
|
||||||
super.onEnd(mousePos);
|
super.onEnd(mousePos, mouseTarget);
|
||||||
|
|
||||||
|
if (!this.selectionTool.cursorInSelectedArea(mousePos) &&
|
||||||
|
!Util.isChildOfByClass(mouseTarget, "editor-top-menu")) {
|
||||||
|
this.endSelection();
|
||||||
|
// Switch to selection tool
|
||||||
|
this.switchFunc(this.selectionTool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelect() {
|
onSelect() {
|
||||||
@ -113,7 +126,5 @@ class MoveSelectionTool extends DrawingTool {
|
|||||||
return;
|
return;
|
||||||
this.currSelection = undefined;
|
this.currSelection = undefined;
|
||||||
this.selectionTool.pasteSelection();
|
this.selectionTool.pasteSelection();
|
||||||
// Switch to brush
|
|
||||||
this.switchFunc(this.endTool);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,14 +8,6 @@ class RectangularSelectionTool extends SelectionTool {
|
|||||||
onStart(mousePos) {
|
onStart(mousePos) {
|
||||||
super.onStart(mousePos);
|
super.onStart(mousePos);
|
||||||
|
|
||||||
// Putting the vfx layer on top of everything
|
|
||||||
currFile.VFXLayer.canvas.style.zIndex = MAX_Z_INDEX;
|
|
||||||
|
|
||||||
// Saving the start coords of the rect
|
|
||||||
this.startMousePos = [Math.floor(mousePos[0] / currFile.zoom),
|
|
||||||
Math.floor(mousePos[1] / currFile.zoom)];
|
|
||||||
this.endMousePos = [this.startMousePos[0], this.startMousePos[1]];
|
|
||||||
|
|
||||||
// Avoiding external selections
|
// Avoiding external selections
|
||||||
if (this.startMousePos[0] < 0) {
|
if (this.startMousePos[0] < 0) {
|
||||||
this.startMousePos[0] = 0;
|
this.startMousePos[0] = 0;
|
||||||
@ -85,51 +77,6 @@ class RectangularSelectionTool extends SelectionTool {
|
|||||||
this.currSelection.width, this.currSelection.height);
|
this.currSelection.width, this.currSelection.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteSelection() {
|
|
||||||
super.pasteSelection();
|
|
||||||
if (this.currSelection == undefined)
|
|
||||||
return;
|
|
||||||
// Clearing the tmp (move preview) and vfx (ants) layers
|
|
||||||
currFile.TMPLayer.context.clearRect(0, 0, currFile.TMPLayer.canvas.width, currFile.TMPLayer.canvas.height);
|
|
||||||
currFile.VFXLayer.context.clearRect(0, 0, currFile.VFXLayer.canvas.width, currFile.VFXLayer.canvas.height);
|
|
||||||
|
|
||||||
// I have to save the underlying data, so that the transparent pixels in the clipboard
|
|
||||||
// don't override the coloured pixels in the canvas
|
|
||||||
let underlyingImageData = currFile.currentLayer.context.getImageData(
|
|
||||||
this.currSelection.left, this.currSelection.top,
|
|
||||||
this.currSelection.width+1, this.currSelection.height+1
|
|
||||||
);
|
|
||||||
let pasteData = this.currSelection.data.data.slice();
|
|
||||||
|
|
||||||
for (let i=0; i<underlyingImageData.data.length; i+=4) {
|
|
||||||
let currentMovePixel = [
|
|
||||||
pasteData[i], pasteData[i+1], pasteData[i+2], pasteData[i+3]
|
|
||||||
];
|
|
||||||
|
|
||||||
let currentUnderlyingPixel = [
|
|
||||||
underlyingImageData.data[i], underlyingImageData.data[i+1],
|
|
||||||
underlyingImageData.data[i+2], underlyingImageData.data[i+3]
|
|
||||||
];
|
|
||||||
|
|
||||||
// If the pixel of the clipboard is empty, but the one below it isn't, I use the pixel below
|
|
||||||
if (Util.isPixelEmpty(currentMovePixel)) {
|
|
||||||
if (!Util.isPixelEmpty(currentUnderlyingPixel)) {
|
|
||||||
pasteData[i] = currentUnderlyingPixel[0];
|
|
||||||
pasteData[i+1] = currentUnderlyingPixel[1];
|
|
||||||
pasteData[i+2] = currentUnderlyingPixel[2];
|
|
||||||
pasteData[i+3] = currentUnderlyingPixel[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currFile.currentLayer.context.putImageData(new ImageData(pasteData, this.currSelection.width+1),
|
|
||||||
this.currSelection.left, this.currSelection.top
|
|
||||||
);
|
|
||||||
|
|
||||||
currFile.currentLayer.updateLayerPreview();
|
|
||||||
currFile.VFXLayer.canvas.style.zIndex = MIN_Z_INDEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect() {
|
onSelect() {
|
||||||
super.onSelect();
|
super.onSelect();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/** TODO
|
/** TODO
|
||||||
* - Once the selected pixels have been obtained, save the selection outline in an image data
|
* - Once the selected pixels have been obtained, save the selection outline in an image data
|
||||||
* - At the same time, create another image data and put the selected pixels in it
|
|
||||||
* - The move tool will then move those image datas and they'll be pasted on the right layer
|
* - The move tool will then move those image datas and they'll be pasted on the right layer
|
||||||
* at the end of the selection
|
* at the end of the selection
|
||||||
*
|
*
|
||||||
@ -18,6 +17,7 @@ class SelectionTool extends Tool {
|
|||||||
selectedPixel = undefined;
|
selectedPixel = undefined;
|
||||||
|
|
||||||
moveOffset = [0, 0];
|
moveOffset = [0, 0];
|
||||||
|
boundingBoxCenter = [0,0];
|
||||||
|
|
||||||
constructor(name, options, switchFunc, moveTool) {
|
constructor(name, options, switchFunc, moveTool) {
|
||||||
super(name, options);
|
super(name, options);
|
||||||
@ -29,6 +29,14 @@ class SelectionTool extends Tool {
|
|||||||
onStart(mousePos) {
|
onStart(mousePos) {
|
||||||
super.onStart(mousePos);
|
super.onStart(mousePos);
|
||||||
|
|
||||||
|
// Putting the vfx layer on top of everything
|
||||||
|
currFile.VFXLayer.canvas.style.zIndex = MAX_Z_INDEX;
|
||||||
|
currFile.VFXLayer.context.fillStyle = "rgba(0,0,0,1)";
|
||||||
|
|
||||||
|
this.startMousePos = [Math.floor(mousePos[0] / currFile.zoom),
|
||||||
|
Math.floor(mousePos[1] / currFile.zoom)];
|
||||||
|
this.endMousePos = [this.startMousePos[0], this.startMousePos[1]];
|
||||||
|
|
||||||
let mouseX = mousePos[0] / currFile.zoom;
|
let mouseX = mousePos[0] / currFile.zoom;
|
||||||
let mouseY = mousePos[1] / currFile.zoom;
|
let mouseY = mousePos[1] / currFile.zoom;
|
||||||
|
|
||||||
@ -40,21 +48,69 @@ class SelectionTool extends Tool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDrag(mousePos) {
|
onDrag(mousePos) {
|
||||||
|
super.onDrag(mousePos);
|
||||||
|
|
||||||
let mouseX = mousePos[0] / currFile.zoom;
|
let mouseX = mousePos[0] / currFile.zoom;
|
||||||
let mouseY = mousePos[1] / currFile.zoom;
|
let mouseY = mousePos[1] / currFile.zoom;
|
||||||
|
|
||||||
this.updateBoundingBox(mouseX, mouseY);
|
this.updateBoundingBox(mouseX, mouseY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEnd(mousePos) {
|
||||||
|
super.onEnd(mousePos);
|
||||||
|
|
||||||
|
this.boundingBoxCenter = [this.boundingBox.minX + (this.boundingBox.maxX - this.boundingBox.minX) / 2,
|
||||||
|
this.boundingBox.minY + (this.boundingBox.maxY - this.boundingBox.minY) / 2];
|
||||||
|
}
|
||||||
|
|
||||||
cutSelection() {}
|
cutSelection() {}
|
||||||
|
|
||||||
pasteSelection(){}
|
pasteSelection(){
|
||||||
|
if (this.currSelection == undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// I have to save the underlying data, so that the transparent pixels in the clipboard
|
||||||
|
// don't override the coloured pixels in the canvas
|
||||||
|
let underlyingImageData = currFile.currentLayer.context.getImageData(0, 0, currFile.canvasSize[0], currFile.canvasSize[1]);
|
||||||
|
let pasteData = currFile.TMPLayer.context.getImageData(0, 0, currFile.canvasSize[0], currFile.canvasSize[1]);
|
||||||
|
|
||||||
|
// Clearing the tmp (move preview) and vfx (ants) layers
|
||||||
|
currFile.TMPLayer.context.clearRect(0, 0, currFile.canvasSize[0], currFile.canvasSize[1]);
|
||||||
|
currFile.VFXLayer.context.clearRect(0, 0, currFile.canvasSize[0], currFile.canvasSize[1]);
|
||||||
|
|
||||||
|
for (let i=0; i<underlyingImageData.data.length; i+=4) {
|
||||||
|
let currentMovePixel = [
|
||||||
|
pasteData.data[i], pasteData.data[i+1], pasteData.data[i+2], pasteData.data[i+3]
|
||||||
|
];
|
||||||
|
|
||||||
|
let currentUnderlyingPixel = [
|
||||||
|
underlyingImageData.data[i], underlyingImageData.data[i+1],
|
||||||
|
underlyingImageData.data[i+2], underlyingImageData.data[i+3]
|
||||||
|
];
|
||||||
|
|
||||||
|
// If the pixel of the clipboard is empty, but the one below it isn't, I use the pixel below
|
||||||
|
if (Util.isPixelEmpty(currentMovePixel)) {
|
||||||
|
if (!Util.isPixelEmpty(currentUnderlyingPixel)) {
|
||||||
|
pasteData.data[i] = currentUnderlyingPixel[0];
|
||||||
|
pasteData.data[i+1] = currentUnderlyingPixel[1];
|
||||||
|
pasteData.data[i+2] = currentUnderlyingPixel[2];
|
||||||
|
pasteData.data[i+3] = currentUnderlyingPixel[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(currFile.canvasSize[0]);
|
||||||
|
currFile.currentLayer.context.putImageData(pasteData, 0, 0);
|
||||||
|
currFile.currentLayer.updateLayerPreview();
|
||||||
|
|
||||||
|
currFile.VFXLayer.canvas.style.zIndex = MIN_Z_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
copySelection(){}
|
copySelection(){}
|
||||||
|
|
||||||
cursorInSelectedArea(mousePos) {
|
cursorInSelectedArea(mousePos) {
|
||||||
let floored = [Math.floor(mousePos[0] / currFile.zoom) + this.moveOffset[0],
|
let floored = [Math.floor(mousePos[0] / currFile.zoom) - this.moveOffset[0],
|
||||||
Math.floor(mousePos[1] / currFile.zoom) + this.moveOffset[1]];
|
Math.floor(mousePos[1] / currFile.zoom) - this.moveOffset[1]];
|
||||||
|
|
||||||
if (this.currSelection[floored] != undefined)
|
if (this.currSelection[floored] != undefined)
|
||||||
return true;
|
return true;
|
||||||
@ -158,6 +214,9 @@ class SelectionTool extends Tool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currFile.currentLayer.context.putImageData(new ImageData(currLayerData, currFile.canvasSize[0]), 0, 0);
|
||||||
|
currFile.TMPLayer.context.putImageData(this.previewData, 0, 0);
|
||||||
|
|
||||||
this.drawSelectedArea();
|
this.drawSelectedArea();
|
||||||
|
|
||||||
return this.previewData;
|
return this.previewData;
|
||||||
@ -168,11 +227,17 @@ class SelectionTool extends Tool {
|
|||||||
let x = parseInt(key.split(",")[0]);
|
let x = parseInt(key.split(",")[0]);
|
||||||
let y = parseInt(key.split(",")[1]);
|
let y = parseInt(key.split(",")[1]);
|
||||||
|
|
||||||
currFile.TMPLayer.context.fillStyle = "rgba(10, 0, 40, 0.3)";
|
currFile.VFXLayer.context.fillStyle = "rgba(10, 0, 40, 0.3)";
|
||||||
currFile.TMPLayer.context.fillRect(x + this.moveOffset[0], y + this.moveOffset[1], 1, 1);
|
currFile.VFXLayer.context.fillRect(x + this.moveOffset[0], y + this.moveOffset[1], 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawOutline() {
|
||||||
|
currFile.VFXLayer.context.clearRect(0, 0, currFile.canvasSize[0], currFile.canvasSize[1]);
|
||||||
|
currFile.VFXLayer.context.putImageData(this.outlineData, this.boundingBox.minX + this.moveOffset[0],
|
||||||
|
this.boundingBox.minY + this.moveOffset[1]);
|
||||||
|
}
|
||||||
|
|
||||||
isBorderOfBox(pixel) {
|
isBorderOfBox(pixel) {
|
||||||
return pixel[0] == this.boundingBox.minX || pixel[0] == this.boundingBox.maxX ||
|
return pixel[0] == this.boundingBox.minX || pixel[0] == this.boundingBox.maxX ||
|
||||||
pixel[1] == this.boundingBox.minY || pixel[1] == this.boundingBox.maxY;
|
pixel[1] == this.boundingBox.minY || pixel[1] == this.boundingBox.maxY;
|
||||||
|
Loading…
Reference in New Issue
Block a user