mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Moved some of _pixelEditorUtility.js functions to proper files
Also left some comments about where to put the leftover functions once we have a more detailed structure.
This commit is contained in:
parent
b8ae07adff
commit
7976675132
@ -18,7 +18,7 @@ const ColorModule = (() => {
|
|||||||
animation:100,
|
animation:100,
|
||||||
filter: ".noshrink",
|
filter: ".noshrink",
|
||||||
draggable: ".draggable-colour",
|
draggable: ".draggable-colour",
|
||||||
onEnd: makeIsDraggingFalse
|
onEnd: function() {dragging = false}
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Changes all of one color to another after being changed from the color picker
|
/** Changes all of one color to another after being changed from the color picker
|
||||||
|
27
js/Input.js
27
js/Input.js
@ -1,4 +1,31 @@
|
|||||||
class Input {
|
class Input {
|
||||||
|
/** Used to programmatically create an input event
|
||||||
|
*
|
||||||
|
* @param {*} keyCode KeyCode of the key to press
|
||||||
|
* @param {*} ctrl Is ctrl pressed?
|
||||||
|
* @param {*} alt Is alt pressed?
|
||||||
|
* @param {*} shift Is shift pressed?
|
||||||
|
*/
|
||||||
|
static simulateInput(keyCode, ctrl, alt, shift) {
|
||||||
|
// I just copy pasted this from stack overflow lol please have mercy
|
||||||
|
let keyboardEvent = document.createEvent("KeyboardEvent");
|
||||||
|
let initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
|
||||||
|
|
||||||
|
keyboardEvent[initMethod](
|
||||||
|
"keydown", // event type: keydown, keyup, keypress
|
||||||
|
true, // bubbles
|
||||||
|
true, // cancelable
|
||||||
|
window, // view: should be window
|
||||||
|
ctrl, // ctrlKey
|
||||||
|
alt, // altKey
|
||||||
|
shift, // shiftKey
|
||||||
|
false, // metaKey
|
||||||
|
keyCode, // keyCode: unsigned long - the virtual key code, else 0
|
||||||
|
keyCode // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
|
||||||
|
);
|
||||||
|
document.dispatchEvent(keyboardEvent);
|
||||||
|
}
|
||||||
|
|
||||||
static on(event, elementId, functionCallback, ...args) {
|
static on(event, elementId, functionCallback, ...args) {
|
||||||
//if element provided is string, get the actual element
|
//if element provided is string, get the actual element
|
||||||
const element = Util.getElement(elementId);
|
const element = Util.getElement(elementId);
|
||||||
|
21
js/Util.js
21
js/Util.js
@ -1,5 +1,26 @@
|
|||||||
// Acts as a public static class
|
// Acts as a public static class
|
||||||
class Util {
|
class Util {
|
||||||
|
|
||||||
|
/** Tells if element is a child of an element with class className
|
||||||
|
*
|
||||||
|
* @param {*} element
|
||||||
|
* @param {*} className
|
||||||
|
*/
|
||||||
|
static isChildOfByClass(element, className) {
|
||||||
|
// Getting the element with class className
|
||||||
|
while (element != null && element.classList != null && !element.classList.contains(className)) {
|
||||||
|
element = element.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If that element exists and its class is the correct one
|
||||||
|
if (element != null && element.classList != null && element.classList.contains(className)) {
|
||||||
|
// Then element is a chld of an element with class className
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns elementOrElementId if the argument is already an element, otherwise it finds
|
/** Returns elementOrElementId if the argument is already an element, otherwise it finds
|
||||||
* the element by its ID (given by the argument) and returns it
|
* the element by its ID (given by the argument) and returns it
|
||||||
*
|
*
|
||||||
|
41
js/_layer.js
41
js/_layer.js
@ -467,8 +467,6 @@ function duplicateLayer(event, saveHistory = true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renameLayer(event) {
|
function renameLayer(event) {
|
||||||
let layerIndex = layers.indexOf(currentLayer);
|
|
||||||
let toRename = currentLayer;
|
|
||||||
let p = currentLayer.menuEntry.getElementsByTagName("p")[0];
|
let p = currentLayer.menuEntry.getElementsByTagName("p")[0];
|
||||||
|
|
||||||
oldLayerName = p.innerHTML;
|
oldLayerName = p.innerHTML;
|
||||||
@ -477,7 +475,7 @@ function renameLayer(event) {
|
|||||||
p.classList.add("layer-name-editable");
|
p.classList.add("layer-name-editable");
|
||||||
p.focus();
|
p.focus();
|
||||||
|
|
||||||
simulateInput(65, true, false, false);
|
Input.simulateInput(65, true, false, false);
|
||||||
|
|
||||||
isRenamingLayer = true;
|
isRenamingLayer = true;
|
||||||
}
|
}
|
||||||
@ -597,6 +595,43 @@ function layerDragDrop(event) {
|
|||||||
dragging = false;
|
dragging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Merges topLayer onto belowLayer
|
||||||
|
*
|
||||||
|
* @param {*} belowLayer The layer on the bottom of the layer stack
|
||||||
|
* @param {*} topLayer The layer on the top of the layer stack
|
||||||
|
*/
|
||||||
|
function mergeLayers(belowLayer, topLayer) {
|
||||||
|
// Copying the above content on the layerBelow
|
||||||
|
let belowImageData = belowLayer.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
let toMergeImageData = topLayer.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
for (let i=0; i<belowImageData.data.length; i+=4) {
|
||||||
|
let currentMovePixel = [
|
||||||
|
toMergeImageData.data[i], toMergeImageData.data[i+1],
|
||||||
|
toMergeImageData.data[i+2], toMergeImageData.data[i+3]
|
||||||
|
];
|
||||||
|
|
||||||
|
let currentUnderlyingPixel = [
|
||||||
|
belowImageData.data[i], belowImageData.data[i+1],
|
||||||
|
belowImageData.data[i+2], belowImageData.data[i+3]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isPixelEmpty(currentMovePixel)) {
|
||||||
|
if (!isPixelEmpty(belowImageData)) {
|
||||||
|
toMergeImageData.data[i] = currentUnderlyingPixel[0];
|
||||||
|
toMergeImageData.data[i+1] = currentUnderlyingPixel[1];
|
||||||
|
toMergeImageData.data[i+2] = currentUnderlyingPixel[2];
|
||||||
|
toMergeImageData.data[i+3] = currentUnderlyingPixel[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Putting the top data into the belowdata
|
||||||
|
belowLayer.putImageData(toMergeImageData, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
layerList = document.getElementById("layers-menu");
|
layerList = document.getElementById("layers-menu");
|
||||||
|
|
||||||
// Making the layers list sortable
|
// Making the layers list sortable
|
||||||
|
@ -72,7 +72,7 @@ window.addEventListener("mouseup", function (mouseEvent) {
|
|||||||
|
|
||||||
TopMenuModule.closeMenu();
|
TopMenuModule.closeMenu();
|
||||||
|
|
||||||
if (currentLayer != null && !isChildOfByClass(mouseEvent.target, "layers-menu-entry")) {
|
if (currentLayer != null && !Util.isChildOfByClass(mouseEvent.target, "layers-menu-entry")) {
|
||||||
currentLayer.closeOptionsMenu();
|
currentLayer.closeOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,67 +1,6 @@
|
|||||||
/***********MISCELLANEOUS UTILITY FUNCTIONS**************/
|
/***********MISCELLANEOUS UTILITY FUNCTIONS**************/
|
||||||
|
|
||||||
/** Merges topLayer onto belowLayer
|
// REFACTOR: put in Canvas class / IIFE
|
||||||
*
|
|
||||||
* @param {*} belowLayer The layer on the bottom of the layer stack
|
|
||||||
* @param {*} topLayer The layer on the top of the layer stack
|
|
||||||
*/
|
|
||||||
function mergeLayers(belowLayer, topLayer) {
|
|
||||||
// Copying the above content on the layerBelow
|
|
||||||
let belowImageData = belowLayer.getImageData(0, 0, canvas.width, canvas.height);
|
|
||||||
let toMergeImageData = topLayer.getImageData(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
for (let i=0; i<belowImageData.data.length; i+=4) {
|
|
||||||
let currentMovePixel = [
|
|
||||||
toMergeImageData.data[i], toMergeImageData.data[i+1],
|
|
||||||
toMergeImageData.data[i+2], toMergeImageData.data[i+3]
|
|
||||||
];
|
|
||||||
|
|
||||||
let currentUnderlyingPixel = [
|
|
||||||
belowImageData.data[i], belowImageData.data[i+1],
|
|
||||||
belowImageData.data[i+2], belowImageData.data[i+3]
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isPixelEmpty(currentMovePixel)) {
|
|
||||||
if (!isPixelEmpty(belowImageData)) {
|
|
||||||
toMergeImageData.data[i] = currentUnderlyingPixel[0];
|
|
||||||
toMergeImageData.data[i+1] = currentUnderlyingPixel[1];
|
|
||||||
toMergeImageData.data[i+2] = currentUnderlyingPixel[2];
|
|
||||||
toMergeImageData.data[i+3] = currentUnderlyingPixel[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Putting the top data into the belowdata
|
|
||||||
belowLayer.putImageData(toMergeImageData, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used to programmatically create an input event
|
|
||||||
*
|
|
||||||
* @param {*} keyCode KeyCode of the key to press
|
|
||||||
* @param {*} ctrl Is ctrl pressed?
|
|
||||||
* @param {*} alt Is alt pressed?
|
|
||||||
* @param {*} shift Is shift pressed?
|
|
||||||
*/
|
|
||||||
function simulateInput(keyCode, ctrl, alt, shift) {
|
|
||||||
// I just copy pasted this from stack overflow lol please have mercy
|
|
||||||
let keyboardEvent = document.createEvent("KeyboardEvent");
|
|
||||||
let initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
|
|
||||||
|
|
||||||
keyboardEvent[initMethod](
|
|
||||||
"keydown", // event type: keydown, keyup, keypress
|
|
||||||
true, // bubbles
|
|
||||||
true, // cancelable
|
|
||||||
window, // view: should be window
|
|
||||||
ctrl, // ctrlKey
|
|
||||||
alt, // altKey
|
|
||||||
shift, // shiftKey
|
|
||||||
false, // metaKey
|
|
||||||
keyCode, // keyCode: unsigned long - the virtual key code, else 0
|
|
||||||
keyCode // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
|
|
||||||
);
|
|
||||||
document.dispatchEvent(keyboardEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Tells if a pixel is empty (has alpha = 0)
|
/** Tells if a pixel is empty (has alpha = 0)
|
||||||
*
|
*
|
||||||
* @param {*} pixel
|
* @param {*} pixel
|
||||||
@ -79,26 +18,7 @@ function isPixelEmpty(pixel) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tells if element is a child of an element with class className
|
// REFACTOR: move to eyedropper onMouseUp event?
|
||||||
*
|
|
||||||
* @param {*} element
|
|
||||||
* @param {*} className
|
|
||||||
*/
|
|
||||||
function isChildOfByClass(element, className) {
|
|
||||||
// Getting the element with class className
|
|
||||||
while (element != null && element.classList != null && !element.classList.contains(className)) {
|
|
||||||
element = element.parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If that element exists and its class is the correct one
|
|
||||||
if (element != null && element.classList != null && element.classList.contains(className)) {
|
|
||||||
// Then element is a chld of an element with class className
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the eyedropped colour (the colour of the pixel pointed by the cursor when the user is using the eyedropper).
|
/** Gets the eyedropped colour (the colour of the pixel pointed by the cursor when the user is using the eyedropper).
|
||||||
* It takes the colour of the canvas with the biggest z-index, basically the one the user can see, since it doesn't
|
* It takes the colour of the canvas with the biggest z-index, basically the one the user can see, since it doesn't
|
||||||
* make much sense to sample a colour which is hidden behind a different layer
|
* make much sense to sample a colour which is hidden behind a different layer
|
||||||
@ -135,24 +55,7 @@ function getEyedropperColor(cursorLocation) {
|
|||||||
return selectedColor;
|
return selectedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the absolute position of the element (position on the screen)
|
// REFACTOR: private method of custom ImageData wrapper (PixelImageData?)?
|
||||||
*
|
|
||||||
* @param {*} element The element of which we have to get the position
|
|
||||||
*/
|
|
||||||
function getElementAbsolutePosition(element) {
|
|
||||||
// Probably copy pasted this from stack overflow too, if not I don't recall how it works
|
|
||||||
let curleft = curtop = 0;
|
|
||||||
|
|
||||||
if (element.offsetParent) {
|
|
||||||
do {
|
|
||||||
curleft += element.offsetLeft;
|
|
||||||
curtop += element.offsetTop;
|
|
||||||
} while (element = element.offsetParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [curleft,curtop];
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Nearest neighbor algorithm to scale a sprite
|
/** Nearest neighbor algorithm to scale a sprite
|
||||||
*
|
*
|
||||||
* @param {*} src The source imageData
|
* @param {*} src The source imageData
|
||||||
@ -177,6 +80,7 @@ function nearestNeighbor (src, dst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REFACTOR: private method of custom ImageData wrapper (PixelImageData?)?
|
||||||
/** Bilinear interpolation used to scale a sprite
|
/** Bilinear interpolation used to scale a sprite
|
||||||
*
|
*
|
||||||
* @param {*} src The source imageData
|
* @param {*} src The source imageData
|
||||||
@ -226,6 +130,7 @@ function bilinearInterpolation (src, dst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REFACTOR: public static method of custom ImageData wrapper (PixelImageData?)?
|
||||||
/** Resizes an imageData depending on the algorithm and on the new width and height
|
/** Resizes an imageData depending on the algorithm and on the new width and height
|
||||||
*
|
*
|
||||||
* @param {*} image The imageData to scale
|
* @param {*} image The imageData to scale
|
||||||
@ -250,6 +155,7 @@ function resizeImageData (image, width, height, algorithm) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REFACTOR: public static method of custom ImageData wrapper (PixelImageData?)?
|
||||||
/** Gets the position in (x, y) format of the pixel with index "index"
|
/** Gets the position in (x, y) format of the pixel with index "index"
|
||||||
*
|
*
|
||||||
* @param {*} index The index of the pixel of which we need the (x, y) position
|
* @param {*} index The index of the pixel of which we need the (x, y) position
|
||||||
@ -261,10 +167,3 @@ function getPixelPosition(index) {
|
|||||||
|
|
||||||
return [Math.ceil(x), Math.ceil(y)];
|
return [Math.ceil(x), Math.ceil(y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets isDragging to false, used when the user interacts with sortable lists
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function makeIsDraggingFalse(event) {
|
|
||||||
dragging = false;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user