mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Added ResizableTool and SelectionTool
This commit is contained in:
parent
2d8974f9d6
commit
a56d7092fc
@ -9,7 +9,7 @@ const ToolManager = (() => {
|
||||
panTool = new PanTool("pan", {type: 'custom'}, switchTool);
|
||||
zoomTool = new ZoomTool("zoom", {type:'custom'});
|
||||
|
||||
rectSelectTool = new RectangularSelectionTool("rectangularselection",
|
||||
rectSelectTool = new RectangularSelectionTool("rectselect",
|
||||
{type: 'cursor', style:'crosshair'}, switchTool);
|
||||
moveSelectionTool = new MoveSelectionTool("moveselection",
|
||||
{type:'cursor', style:'crosshair'}, switchTool);
|
||||
|
@ -1,444 +0,0 @@
|
||||
// REFACTOR: let's keep this one global for now, unfortunately it's used by just some tools to keep track of
|
||||
// their state: I'd wait after we refactor the tools themselves before removing this variable, which should
|
||||
// ideally be updated in Input.js what a mess what a mess what a mess what a mess
|
||||
/*
|
||||
var lastMouseMovePos;
|
||||
|
||||
//mousedown - start drawing
|
||||
window.addEventListener("mousedown", function (mouseEvent) {
|
||||
canDraw = true;
|
||||
|
||||
//if no document has been created yet, or this is a dialog open, or the currentLayer is locked
|
||||
if (!Startup.documentCreated() || Dialogue.isOpen() || currentLayer.isLocked ||
|
||||
!currentLayer.isVisible) return;
|
||||
//prevent right mouse clicks and such, which will open unwanted menus
|
||||
//mouseEvent.preventDefault();
|
||||
|
||||
lastMouseClickPos = Input.getCursorPosition(mouseEvent);
|
||||
|
||||
//left or right click ?
|
||||
if (mouseEvent.which == 1) {
|
||||
if (Input.spacePressed())
|
||||
currentTool = tool.pan;
|
||||
else if (mouseEvent.altKey)
|
||||
currentTool = tool.eyedropper;
|
||||
else if (mouseEvent.target.className == 'drawingCanvas' &&
|
||||
(currentTool.name == 'pencil' || currentTool.name == 'eraser' || currentTool.name == 'rectangle' || currentTool.name == 'ellipse' || currentTool.name === 'line'))
|
||||
new HistoryState().EditCanvas();
|
||||
else if (currentTool.name == 'moveselection') {
|
||||
if (!cursorInSelectedArea() &&
|
||||
((mouseEvent.target.id == 'canvas-view') || mouseEvent.target.className == 'drawingCanvas')) {
|
||||
tool.pencil.switchTo();
|
||||
canDraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentLayer.isLocked && !currentLayer.isVisible && canDraw) {
|
||||
draw(mouseEvent);
|
||||
}
|
||||
}
|
||||
else if (mouseEvent.which == 2) {
|
||||
tool.pan.brushSize = currentTool.brushSize;
|
||||
currentTool = tool.pan;
|
||||
}
|
||||
else if (currentTool.name == 'pencil' && mouseEvent.which == 3) {
|
||||
currentTool = tool.resizebrush;
|
||||
tool.pencil.previousBrushSize = tool.pencil.brushSize;
|
||||
}
|
||||
else if (currentTool.name == 'eraser' && mouseEvent.which == 3) {
|
||||
currentTool = tool.resizeeraser;
|
||||
tool.eraser.previousBrushSize = tool.eraser.brushSize;
|
||||
}
|
||||
// TODO: [ELLIPSE] Do we need similar logic related to ellipse?
|
||||
else if (currentTool.name == 'rectangle' && mouseEvent.which == 3) {
|
||||
currentTool = tool.resizerectangle;
|
||||
tool.rectangle.previousBrushSize = tool.rectangle.brushSize;
|
||||
}
|
||||
else if (currentTool.name == 'line' && mouseEvent.which == 3) {
|
||||
currentTool = tool.resizeline;
|
||||
tool.line.previousBrushSize = tool.line.brushSize;
|
||||
}
|
||||
|
||||
if (currentTool.name == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas')
|
||||
eyedropperPreview.style.display = 'block';
|
||||
|
||||
return false;
|
||||
}, false);
|
||||
|
||||
|
||||
|
||||
//mouseup - end drawing
|
||||
window.addEventListener("mouseup", function (mouseEvent) {
|
||||
TopMenuModule.closeMenu();
|
||||
|
||||
if (currentLayer != null && !Util.isChildOfByClass(mouseEvent.target, "layers-menu-entry")) {
|
||||
LayerList.closeOptionsMenu();
|
||||
}
|
||||
|
||||
// If the user finished placing down a line, clear the tmp canvas and copy the data to the current layer
|
||||
if (currentTool.name === "line") {
|
||||
const tmpCanvas = TMPLayer.canvas;
|
||||
currentLayer.context.drawImage(tmpCanvas, 0, 0);
|
||||
|
||||
const tmpContext = TMPLayer.context;
|
||||
tmpContext.clearRect(0, 0, tmpCanvas.width, tmpCanvas.height);
|
||||
}
|
||||
|
||||
if (!Startup.documentCreated() || Dialogue.isOpen() || !currentLayer.isVisible ||
|
||||
currentLayer.isLocked) return;
|
||||
|
||||
if (currentTool.name == 'eyedropper' && mouseEvent.target.className == 'drawingCanvas') {
|
||||
var cursorLocation = Input.getCursorPosition(mouseEvent);
|
||||
var selectedColor = getEyedropperColor(cursorLocation);
|
||||
const rgbColor = {r:selectedColor[0],g:selectedColor[1],b:selectedColor[2]};
|
||||
var newColor = Color.rgbToHex(rgbColor);
|
||||
|
||||
ColorModule.updateCurrentColor('#' + newColor);
|
||||
|
||||
let colors = document.getElementsByClassName('color-button');
|
||||
for (let i = 0; i < colors.length; i++) {
|
||||
|
||||
//if picked color matches this color
|
||||
if (newColor == colors[i].jscolor.toString()) {
|
||||
//remove current color selection
|
||||
document.querySelector("#colors-menu li.selected")?.classList.remove("selected");
|
||||
|
||||
//set current color
|
||||
|
||||
for (let i=2; i<layers.length; i++) {
|
||||
layers[i].context.fillStyle = '#' + newColor;
|
||||
}
|
||||
|
||||
//make color selected
|
||||
colors[i].parentElement.classList.add('selected');
|
||||
|
||||
//hide eyedropper
|
||||
eyedropperPreview.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentTool.name == 'fill' && mouseEvent.target.className == 'drawingCanvas') {
|
||||
|
||||
//get cursor postion
|
||||
var cursorLocation = Input.getCursorPosition(mouseEvent);
|
||||
|
||||
//offset to match cursor point
|
||||
cursorLocation[0] += 2;
|
||||
cursorLocation[1] += 12;
|
||||
|
||||
//fill starting at the location
|
||||
fill(cursorLocation);
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
else if (currentTool.name == 'zoom' && mouseEvent.target.className == 'drawingCanvas') {
|
||||
let mode;
|
||||
if (mouseEvent.which == 1){
|
||||
mode = "in";
|
||||
}
|
||||
}
|
||||
else if (currentTool == 'zoom' && mouseEvent.target.className == 'drawingCanvas') {
|
||||
let mode;
|
||||
if (mouseEvent.which == 1){
|
||||
mode = 'in';
|
||||
}
|
||||
else if (mouseEvent.which == 3){
|
||||
mode = 'out';
|
||||
}
|
||||
|
||||
changeZoom(mode, Input.getCursorPosition(mouseEvent));
|
||||
|
||||
for (let i=1; i<layers.length; i++) {
|
||||
layers[i].copyData(layers[0]);
|
||||
}
|
||||
}
|
||||
else if (currentTool.name == 'rectselect' && isRectSelecting) {
|
||||
endRectSelection(mouseEvent);
|
||||
}
|
||||
else if (currentTool.name == 'rectangle' && isDrawingRect) {
|
||||
endRectDrawing(mouseEvent);
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
else if (currentTool.name == 'ellipse' && isDrawingEllipse) {
|
||||
endEllipseDrawing(mouseEvent);
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
|
||||
currentTool = currentToolTemp;
|
||||
|
||||
ToolManager.currentTool().updateCursor();
|
||||
var cursorLocation = Input.getCursorPosition(mouseEvent);
|
||||
currentTool.moveBrushPreview(cursorLocation);
|
||||
|
||||
|
||||
}, false);
|
||||
|
||||
function setPreviewPosition(preview, size){
|
||||
let toAdd = 0;
|
||||
|
||||
// This prevents the brush to be placed in the middle of pixels
|
||||
if (size % 2 == 0) {
|
||||
toAdd = 0.5;
|
||||
}
|
||||
|
||||
preview.style.left = (
|
||||
currentLayer.canvas.offsetLeft
|
||||
+ Math.floor(cursor[0]/zoom) * zoom
|
||||
- Math.floor(size / 2) * zoom + toAdd
|
||||
) + 'px';
|
||||
preview.style.top = (
|
||||
currentLayer.canvas.offsetTop
|
||||
+ Math.floor(cursor[1]/zoom) * zoom
|
||||
- Math.floor(size / 2) * zoom + toAdd
|
||||
) + 'px';
|
||||
}
|
||||
|
||||
|
||||
// OPTIMIZABLE: redundant || mouseEvent.target.className in currentTool ifs
|
||||
|
||||
//mouse is moving on canvas
|
||||
window.addEventListener("mousemove", draw, false);
|
||||
window.addEventListener("mousedown", draw, false);
|
||||
|
||||
function draw (mouseEvent) {
|
||||
if (!Dialogue.isOpen())
|
||||
{
|
||||
lastMouseMovePos = Input.getCursorPosition(mouseEvent);
|
||||
|
||||
var cursorLocation = lastMouseMovePos;
|
||||
|
||||
//if a document hasnt yet been created or the current layer is locked, exit this function
|
||||
if (!Startup.documentCreated() || Dialogue.isOpen() || !currentLayer.isVisible ||
|
||||
currentLayer.isLocked) return;
|
||||
|
||||
// Moving brush preview
|
||||
currentTool.moveBrushPreview(cursorLocation);
|
||||
// Hiding eyedropper, will be shown if it's needed
|
||||
eyedropperPreview.style.display = 'none';
|
||||
|
||||
if (currentTool.name == 'pencil') {
|
||||
|
||||
//draw line to current pixel
|
||||
if (Input.isDragging()) {
|
||||
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas') {
|
||||
line(Math.floor(lastMouseClickPos[0]/zoom),
|
||||
Math.floor(lastMouseClickPos[1]/zoom),
|
||||
Math.floor(cursorLocation[0]/zoom),
|
||||
Math.floor(cursorLocation[1]/zoom),
|
||||
tool.pencil.brushSize
|
||||
);
|
||||
lastMouseClickPos = cursorLocation;
|
||||
}
|
||||
}
|
||||
|
||||
//get lightness value of color
|
||||
var selectedColor = currentLayer.context.getImageData(Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom),1,1).data;
|
||||
var colorLightness = Math.max(selectedColor[0],selectedColor[1],selectedColor[2])
|
||||
|
||||
//for the darkest 75% of colors, change the brush preview to dark mode
|
||||
if (colorLightness>64) brushPreview.classList.remove('dark');
|
||||
else brushPreview.classList.add('dark');
|
||||
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
// Decided to write a different implementation in case of differences between the brush and the eraser tool
|
||||
else if (currentTool.name == 'eraser') {
|
||||
//hide brush preview outside of canvas / canvas view
|
||||
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas')
|
||||
brushPreview.style.visibility = 'visible';
|
||||
else
|
||||
brushPreview.style.visibility = 'hidden';
|
||||
|
||||
//draw line to current pixel
|
||||
if (Input.isDragging()) {
|
||||
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas') {
|
||||
line(Math.floor(lastMouseClickPos[0]/zoom),Math.floor(lastMouseClickPos[1]/zoom),Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom), currentTool.brushSize);
|
||||
lastMouseClickPos = cursorLocation;
|
||||
}
|
||||
}
|
||||
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
else if (currentTool.name == 'rectangle')
|
||||
{
|
||||
//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 && Input.isDragging()) {
|
||||
startRectDrawing(mouseEvent);
|
||||
}
|
||||
else if (Input.isDragging()){
|
||||
updateRectDrawing(mouseEvent);
|
||||
}
|
||||
}
|
||||
else if (currentTool.name == 'ellipse')
|
||||
{
|
||||
//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 (!isDrawingEllipse && Input.isDragging()) {
|
||||
startEllipseDrawing(mouseEvent);
|
||||
}
|
||||
else if (Input.isDragging()){
|
||||
updateEllipseDrawing(mouseEvent);
|
||||
}
|
||||
}
|
||||
else if (currentTool.name == 'pan' && Input.isDragging()) {
|
||||
// Setting first layer position
|
||||
layers[0].setCanvasOffset(layers[0].canvas.offsetLeft + (cursorLocation[0] - lastMouseClickPos[0]), layers[0].canvas.offsetTop + (cursorLocation[1] - lastMouseClickPos[1]));
|
||||
// Copying that position to the other layers
|
||||
for (let i=1; i<layers.length; i++) {
|
||||
layers[i].copyData(layers[0]);
|
||||
}
|
||||
// Updating cursorLocation with new layer position
|
||||
lastMouseMovePos = Input.getCursorPosition(mouseEvent);
|
||||
cursorLocation = lastMouseMovePos;
|
||||
// Moving brush preview
|
||||
currentTool.moveBrushPreview(cursorLocation);
|
||||
}
|
||||
else if (currentTool.name == 'eyedropper' && Input.isDragging() && mouseEvent.target.className == 'drawingCanvas') {
|
||||
|
||||
const selectedColor = getEyedropperColor(cursorLocation);
|
||||
const rgbColor = {r:selectedColor[0],g:selectedColor[1],b:selectedColor[2]};
|
||||
|
||||
eyedropperPreview.style.borderColor = '#' + Color.rgbToHex(rgbColor);
|
||||
eyedropperPreview.style.display = 'block';
|
||||
|
||||
eyedropperPreview.style.left = cursorLocation[0] + currentLayer.canvas.offsetLeft - 30 + 'px';
|
||||
eyedropperPreview.style.top = cursorLocation[1] + currentLayer.canvas.offsetTop - 30 + 'px';
|
||||
|
||||
const colorLightness = Math.max(selectedColor[0],selectedColor[1],selectedColor[2]);
|
||||
|
||||
//for the darkest 50% of colors, change the eyedropper preview to dark mode
|
||||
if (colorLightness>127) eyedropperPreview.classList.remove('dark');
|
||||
else eyedropperPreview.classList.add('dark');
|
||||
}
|
||||
else if (currentTool.name == 'resizebrush' && Input.isDragging()) {
|
||||
//get new brush size based on x distance from original clicking location
|
||||
var distanceFromClick = cursorLocation[0] - lastMouseClickPos[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 brushSizeChange = Math.round(distanceFromClick/10);
|
||||
var newBrushSize = tool.pencil.previousBrushSize + brushSizeChange;
|
||||
|
||||
//set the brush to the new size as long as its bigger than 1
|
||||
tool.pencil.brushSize = Math.max(1,newBrushSize);
|
||||
|
||||
//fix offset so the cursor stays centered
|
||||
tool.pencil.moveBrushPreview(lastMouseClickPos);
|
||||
ToolManager.currentTool().updateCursor();
|
||||
}
|
||||
else if (currentTool.name == 'resizeeraser' && Input.isDragging()) {
|
||||
//get new brush size based on x distance from original clicking location
|
||||
var distanceFromClick = cursorLocation[0] - lastMouseClickPos[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 eraserSizeChange = Math.round(distanceFromClick/10);
|
||||
var newEraserSizeChange = tool.eraser.previousBrushSize + eraserSizeChange;
|
||||
|
||||
//set the brush to the new size as long as its bigger than 1
|
||||
tool.eraser.brushSize = Math.max(1,newEraserSizeChange);
|
||||
|
||||
//fix offset so the cursor stays centered
|
||||
tool.eraser.moveBrushPreview(lastMouseClickPos);
|
||||
ToolManager.currentTool().updateCursor();
|
||||
}
|
||||
else if (currentTool.name == 'resizerectangle' && Input.isDragging()) {
|
||||
//get new brush size based on x distance from original clicking location
|
||||
var distanceFromClick = cursorLocation[0] - lastMouseClickPos[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);
|
||||
// TODO: [ELLIPSE] Do we need similar logic related to ellipse?
|
||||
var newRectangleSize = tool.rectangle.previousBrushSize + rectangleSizeChange;
|
||||
|
||||
//set the brush to the new size as long as its bigger than 1
|
||||
// TODO: [ELLIPSE] Do we need similar logic related to ellipse?
|
||||
tool.rectangle.brushSize = Math.max(1,newRectangleSize);
|
||||
|
||||
//fix offset so the cursor stays centered
|
||||
// TODO: [ELLIPSE] Do we need similar logic related to ellipse?
|
||||
tool.rectangle.moveBrushPreview(lastMouseClickPos);
|
||||
ToolManager.currentTool().updateCursor();
|
||||
}
|
||||
else if (currentTool.name == 'resizeline' && Input.isDragging()) {
|
||||
//get new brush size based on x distance from original clicking location
|
||||
var distanceFromClick = cursorLocation[0] - lastMouseClickPos[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 lineSizeChange = Math.round(distanceFromClick/10);
|
||||
var newLineSize = tool.line.previousBrushSize + lineSizeChange;
|
||||
|
||||
//set the brush to the new size as long as its bigger than 1
|
||||
tool.line.brushSize = Math.max(1, newLineSize);
|
||||
|
||||
//fix offset so the cursor stays centered
|
||||
tool.line.moveBrushPreview(lastMouseClickPos);
|
||||
ToolManager.currentTool().updateCursor();
|
||||
}
|
||||
else if (currentTool.name == 'rectselect') {
|
||||
if (Input.isDragging() && !isRectSelecting && mouseEvent.target.className == 'drawingCanvas') {
|
||||
isRectSelecting = true;
|
||||
startRectSelection(mouseEvent);
|
||||
}
|
||||
else if (Input.isDragging() && isRectSelecting) {
|
||||
updateRectSelection(mouseEvent);
|
||||
}
|
||||
else if (isRectSelecting) {
|
||||
endRectSelection();
|
||||
}
|
||||
}
|
||||
else if (currentTool.name == 'moveselection') {
|
||||
// Updating the cursor (move if inside rect, cross if not)
|
||||
ToolManager.currentTool().updateCursor();
|
||||
|
||||
// If I'm dragging, I move the preview
|
||||
if (Input.isDragging() && cursorInSelectedArea()) {
|
||||
updateMovePreview(Input.getCursorPosition(mouseEvent));
|
||||
}
|
||||
}
|
||||
else if (currentTool.name === "line") {
|
||||
if (mouseEvent.target.className == 'drawingCanvas'|| mouseEvent.target.className == 'drawingCanvas') {
|
||||
brushPreview.style.visibility = 'visible';
|
||||
} else {
|
||||
brushPreview.style.visibility = 'hidden';
|
||||
}
|
||||
if (Input.isDragging()) {
|
||||
if (mouseEvent.target.className == 'drawingCanvas' || mouseEvent.target.className == 'drawingCanvas') {
|
||||
diagLine(lastMouseClickPos, zoom, cursorLocation);
|
||||
}
|
||||
}
|
||||
currentLayer.updateLayerPreview();
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.target.className == 'drawingCanvas')
|
||||
ToolManager.currentTool().updateCursor();
|
||||
else
|
||||
canvasView.style.cursor = 'default';
|
||||
}
|
||||
|
||||
//mousewheel scroll
|
||||
canvasView.addEventListener("wheel", function(mouseEvent){
|
||||
let mode;
|
||||
if (mouseEvent.deltaY < 0){
|
||||
mode = 'in';
|
||||
}
|
||||
else if (mouseEvent.deltaY > 0) {
|
||||
mode = 'out';
|
||||
}
|
||||
|
||||
// Changing zoom and position of the first layer
|
||||
changeZoom(mode, Input.getCursorPosition(mouseEvent));
|
||||
|
||||
for (let i=1; i<layers.length; i++) {
|
||||
// Copying first layer's data into the other layers
|
||||
layers[i].copyData(layers[0]);
|
||||
}
|
||||
});
|
||||
*/
|
@ -1,90 +1,3 @@
|
||||
// RECT SELECTION TOOL
|
||||
var isRectSelecting = false;
|
||||
let startX;
|
||||
let startY;
|
||||
let endX;
|
||||
let endY;
|
||||
|
||||
/** Starts the selection: saves the canvas, sets the start coordinates
|
||||
*
|
||||
* @param {*} mouseEvent
|
||||
*/
|
||||
function startRectSelection(mouseEvent) {
|
||||
// Saving the canvas
|
||||
new HistoryState().EditCanvas();
|
||||
// Putting the vfx layer on top of everything
|
||||
VFXLayer.canvas.style.zIndex = MAX_Z_INDEX;
|
||||
|
||||
// Saving the start coords of the rect
|
||||
let cursorPos = Input.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;
|
||||
}
|
||||
|
||||
/** Updates the selection
|
||||
*
|
||||
* @param {*} mouseEvent
|
||||
*/
|
||||
function updateRectSelection(mouseEvent) {
|
||||
let pos = Input.getCursorPosition(mouseEvent);
|
||||
|
||||
// Drawing the rect
|
||||
drawRect(Math.round(pos[0] / zoom) + 0.5, Math.round(pos[1] / zoom) + 0.5);
|
||||
}
|
||||
|
||||
/** Ends the selection: sets the end coordiantes
|
||||
*
|
||||
* @param {*} mouseEvent
|
||||
*/
|
||||
function endRectSelection(mouseEvent) {
|
||||
// Getting the end position
|
||||
let currentPos = Input.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 = tool.moveselection;
|
||||
currentToolTemp = currentTool;
|
||||
|
||||
// Resetting this
|
||||
isRectSelecting = false;
|
||||
|
||||
// Updating the cursor
|
||||
ToolManager.currentTool().updateCursor();
|
||||
}
|
||||
|
||||
/** Cuts the selection from its canvas and puts it in the tmp layer so it can be moved
|
||||
*
|
||||
* @param {*} mousePosition
|
||||
@ -98,28 +11,6 @@ function cutSelection(mousePosition) {
|
||||
TMPLayer.context.putImageData(imageDataToMove, startX + 1, startY);
|
||||
}
|
||||
|
||||
/** Draws a dashed rectangle representing the selection
|
||||
*
|
||||
* @param {*} x Current end x coordinate of the selection
|
||||
* @param {*} y Current end y coordinate of the selection
|
||||
*/
|
||||
function drawRect(x, y) {
|
||||
// Getting the vfx context
|
||||
let vfxContext = VFXLayer.context;
|
||||
|
||||
// Clearing the vfx canvas
|
||||
vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.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();
|
||||
}
|
||||
|
||||
function applyChanges() {
|
||||
VFXLayer.canvas.style.zIndex = MIN_Z_INDEX;
|
||||
}
|
||||
|
@ -25,9 +25,4 @@ Events.on('click',"ellipse-bigger-button", function(){
|
||||
Events.on('click',"ellipse-smaller-button", function(e){
|
||||
if(tool.ellipse.brushSize > 1)
|
||||
tool.ellipse.brushSize--;
|
||||
}, false);
|
||||
|
||||
//rectangular selection button
|
||||
Events.on('click', "rectselect-button", function(){
|
||||
tool.rectselect.switchTo();
|
||||
}, false);
|
@ -11,8 +11,23 @@
|
||||
|
||||
//=include ColorModule.js
|
||||
//=include _drawLine.js
|
||||
|
||||
//=include _tools.js
|
||||
//=include tools/*.js
|
||||
|
||||
//=include tools/ResizableTool.js
|
||||
//=include tools/SelectionTool.js
|
||||
|
||||
//=include tools/BrushTool.js
|
||||
//=include tools/EraserTool.js
|
||||
//=include tools/LineTool.js
|
||||
//=include tools/RectangleTool.js
|
||||
//=include tools/FillTool.js
|
||||
//=include tools/EyedropperTool.js
|
||||
//=include tools/PanTool.js
|
||||
//=include tools/ZoomTool.js
|
||||
//=include tools/RectangularSelectionTool.js
|
||||
//=include tools/MoveSelectionTool.js
|
||||
|
||||
//=include ToolManager.js
|
||||
|
||||
/**init**/
|
||||
|
@ -1,4 +1,4 @@
|
||||
class BrushTool extends Tool {
|
||||
class BrushTool extends ResizableTool {
|
||||
constructor(name, options, switchFunction) {
|
||||
super(name, options);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
class EraserTool extends Tool {
|
||||
class EraserTool extends ResizableTool {
|
||||
constructor(name, options, switchFunction) {
|
||||
super(name, options);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
class LineTool extends Tool {
|
||||
class LineTool extends ResizableTool {
|
||||
constructor(name, options, switchFunction) {
|
||||
super(name, options);
|
||||
|
||||
|
@ -2,4 +2,24 @@ class MoveSelectionTool extends Tool {
|
||||
constructor (name, options, switchFunc) {
|
||||
super(name, options, switchFunc);
|
||||
}
|
||||
|
||||
onStart(mousePos) {
|
||||
super.onStart(mousePos);
|
||||
}
|
||||
|
||||
onDrag(mousePos) {
|
||||
super.onDrag(mousePos);
|
||||
}
|
||||
|
||||
onEnd(mousePos) {
|
||||
super.onEnd(mousePos);
|
||||
}
|
||||
|
||||
onSelect() {
|
||||
super.onSelect(mousePos);
|
||||
}
|
||||
|
||||
onDeselect() {
|
||||
super.onDeselect(mousePos);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
class RectangleTool extends Tool {
|
||||
class RectangleTool extends ResizableTool {
|
||||
// Saving the empty rect svg
|
||||
emptyRectangleSVG = document.getElementById("rectangle-empty-button-svg");
|
||||
// and the full rect svg so that I can change them when the user changes rect modes
|
||||
|
@ -1,5 +1,91 @@
|
||||
class RectangularSelectionTool extends Tool {
|
||||
class RectangularSelectionTool extends SelectionTool {
|
||||
constructor (name, options, switchFunc) {
|
||||
super(name, options, switchFunc);
|
||||
|
||||
Events.on('click', this.mainButton, switchFunc, this);
|
||||
}
|
||||
|
||||
onStart(mousePos) {
|
||||
super.onStart(mousePos);
|
||||
|
||||
// Saving the canvas
|
||||
new HistoryState().EditCanvas();
|
||||
// Putting the vfx layer on top of everything
|
||||
VFXLayer.canvas.style.zIndex = MAX_Z_INDEX;
|
||||
|
||||
// Saving the start coords of the rect
|
||||
this.startMousePos[0] = Math.round(this.startMousePos[0] / zoom) - 0.5;
|
||||
this.startMousePos[1] = Math.round(this.startMousePos[1] / zoom) - 0.5;
|
||||
|
||||
// Avoiding external selections
|
||||
if (this.startMousePos[0] < 0) {
|
||||
this.startMousePos[0] = 0;
|
||||
}
|
||||
else if (this.startMousePos[0] > currentLayer.canvas.width) {
|
||||
this.startMousePos[0] = currentLayer.canvas.width;
|
||||
}
|
||||
|
||||
if (this.startMousePos[1] < 0) {
|
||||
this.startMousePos[1] = 0;
|
||||
}
|
||||
else if (this.startMousePos[1] > currentLayer.canvas.height) {
|
||||
this.startMousePos[1] = currentLayer.canvas.height;
|
||||
}
|
||||
|
||||
// Drawing the rect
|
||||
this.drawRect(this.startMousePos[0], this.startMousePos[1]);
|
||||
}
|
||||
|
||||
onDrag(mousePos) {
|
||||
super.onDrag(mousePos);
|
||||
|
||||
// Drawing the rect
|
||||
this.drawRect(Math.round(mousePos[0] / zoom) + 0.5, Math.round(mousePos[1] / zoom) + 0.5);
|
||||
}
|
||||
|
||||
onEnd(mousePos) {
|
||||
super.onEnd(mousePos);
|
||||
|
||||
// Getting the end position
|
||||
this.endMousePos[0] = Math.round(this.endMousePos[0] / zoom) + 0.5;
|
||||
this.endMousePos[1] = Math.round(this.endMousePos[1] / zoom) + 0.5;
|
||||
|
||||
// Inverting end and start (start must always be the top left corner)
|
||||
if (this.endMousePos[0] < this.startMousePos[0]) {
|
||||
let tmp = this.endMousePos[0];
|
||||
this.endMousePos[0] = this.startMousePos[0];
|
||||
this.startMousePos[0] = tmp;
|
||||
}
|
||||
// Same for the y
|
||||
if (this.endMousePos[1] < this.startMousePos[1]) {
|
||||
let tmp = this.endMousePos[1];
|
||||
this.endMousePos[1] = this.startMousePos[1];
|
||||
this.startMousePos[1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
onSelect() {
|
||||
super.onSelect();
|
||||
}
|
||||
|
||||
onDeselect() {
|
||||
super.onDeselect();
|
||||
}
|
||||
|
||||
drawRect(x, y) {
|
||||
// Getting the vfx context
|
||||
let vfxContext = VFXLayer.context;
|
||||
|
||||
// Clearing the vfx canvas
|
||||
vfxContext.clearRect(0, 0, VFXLayer.canvas.width, VFXLayer.canvas.height);
|
||||
vfxContext.lineWidth = 1;
|
||||
vfxContext.strokeStyle = 'black';
|
||||
vfxContext.setLineDash([4]);
|
||||
|
||||
// Drawing the rect
|
||||
vfxContext.beginPath();
|
||||
vfxContext.rect(this.startMousePos[0], this.startMousePos[1], x - this.startMousePos[0], y - this.startMousePos[1]);
|
||||
|
||||
vfxContext.stroke();
|
||||
}
|
||||
}
|
5
js/tools/ResizableTool.js
Normal file
5
js/tools/ResizableTool.js
Normal file
@ -0,0 +1,5 @@
|
||||
class ResizableTool extends Tool {
|
||||
constructor(name, options, switchFunc) {
|
||||
super(name, options, switchFunc);
|
||||
}
|
||||
}
|
5
js/tools/SelectionTool.js
Normal file
5
js/tools/SelectionTool.js
Normal file
@ -0,0 +1,5 @@
|
||||
class SelectionTool extends Tool {
|
||||
constructor(name, options, switchFunc) {
|
||||
super(name, options, switchFunc);
|
||||
}
|
||||
}
|
@ -2,28 +2,11 @@ new Tool('resizeline', {
|
||||
cursor: 'default',
|
||||
});
|
||||
|
||||
new Tool('pan', {
|
||||
cursor: function () {
|
||||
if (Input.isDragging()) return 'url(\'/pixel-editor/pan-held.png\'), auto';
|
||||
else return 'url(\'/pixel-editor/pan.png\'), auto';
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
new Tool('ellipse', {
|
||||
cursor: 'none',
|
||||
brushPreview: true,
|
||||
});
|
||||
new Tool('rectselect', {
|
||||
cursor: 'crosshair',
|
||||
brushPreview: true,
|
||||
});
|
||||
|
||||
|
||||
new Tool('moveselection', {
|
||||
cursor: 'crosshair',
|
||||
});
|
||||
|
||||
new Tool('zoom', {
|
||||
imageCursor: 'zoom-in',
|
||||
});
|
Loading…
Reference in New Issue
Block a user