mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Added back eyedropper
This commit is contained in:
parent
d034bbc659
commit
32fb4ca943
@ -444,6 +444,6 @@ const ColorModule = (() => {
|
|||||||
resetPalette,
|
resetPalette,
|
||||||
createColorPalette,
|
createColorPalette,
|
||||||
createPaletteFromLayers,
|
createPaletteFromLayers,
|
||||||
updateCurrentColor
|
updateCurrentColor,
|
||||||
}
|
}
|
||||||
})();
|
})();
|
@ -4,6 +4,7 @@ const ToolManager = (() => {
|
|||||||
rectangleTool = new RectangleTool("rectangle", {type: 'html'}, switchTool);
|
rectangleTool = new RectangleTool("rectangle", {type: 'html'}, switchTool);
|
||||||
lineTool = new LineTool("line", {type: 'html'}, switchTool);
|
lineTool = new LineTool("line", {type: 'html'}, switchTool);
|
||||||
fillTool = new FillTool("fill", {type: 'cursor', pic: 'fill.png'}, switchTool);
|
fillTool = new FillTool("fill", {type: 'cursor', pic: 'fill.png'}, switchTool);
|
||||||
|
eyedropperTool = new EyedropperTool("eyedropper", {type: 'cursor', pic: 'none'}, switchTool);
|
||||||
|
|
||||||
currTool = brushTool;
|
currTool = brushTool;
|
||||||
currTool.onSelect();
|
currTool.onSelect();
|
||||||
|
17
js/Util.js
17
js/Util.js
@ -1,6 +1,23 @@
|
|||||||
// Acts as a public static class
|
// Acts as a public static class
|
||||||
class Util {
|
class Util {
|
||||||
|
|
||||||
|
/** Tells if a pixel is empty (has alpha = 0)
|
||||||
|
*
|
||||||
|
* @param {*} pixel
|
||||||
|
*/
|
||||||
|
static isPixelEmpty(pixel) {
|
||||||
|
if (pixel == null || pixel === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the alpha channel is 0, the current pixel is empty
|
||||||
|
if (pixel[3] == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Tells if element is a child of an element with class className
|
/** Tells if element is a child of an element with class className
|
||||||
*
|
*
|
||||||
* @param {*} element
|
* @param {*} element
|
||||||
|
@ -32,11 +32,6 @@ Events.on('click',"pan-button", function(){
|
|||||||
tool.pan.switchTo();
|
tool.pan.switchTo();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
//eyedropper
|
|
||||||
Events.on('click',"eyedropper-button", function(){
|
|
||||||
tool.eyedropper.switchTo();
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
//rectangular selection button
|
//rectangular selection button
|
||||||
Events.on('click', "rectselect-button", function(){
|
Events.on('click', "rectselect-button", function(){
|
||||||
tool.rectselect.switchTo();
|
tool.rectselect.switchTo();
|
||||||
|
@ -5,8 +5,8 @@ var lastMouseClickPos = [0,0]; // REFACTOR: Input IIFE via getter? <- probably e
|
|||||||
|
|
||||||
//common elements
|
//common elements
|
||||||
// REFACTOR: put brush and eyedropper preview in the respective tool implementations
|
// REFACTOR: put brush and eyedropper preview in the respective tool implementations
|
||||||
|
// REFACTOR: this should be in ResizableTool
|
||||||
var brushPreview = document.getElementById("brush-preview");
|
var brushPreview = document.getElementById("brush-preview");
|
||||||
var eyedropperPreview = document.getElementById("eyedropper-preview");
|
|
||||||
|
|
||||||
// REFACTOR: File class?
|
// REFACTOR: File class?
|
||||||
var canvasView = document.getElementById("canvas-view");
|
var canvasView = document.getElementById("canvas-view");
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/**utilities**/
|
/**utilities**/
|
||||||
//=include lib/cookies.js
|
//=include lib/cookies.js
|
||||||
//=include _jscolor.js
|
//=include _jscolor.js
|
||||||
//=include _pixelEditorUtility.js
|
|
||||||
//=include _variables.js
|
//=include _variables.js
|
||||||
//=include lib/sortable.js
|
//=include lib/sortable.js
|
||||||
//=include Util.js
|
//=include Util.js
|
||||||
@ -10,6 +9,7 @@
|
|||||||
//=include Dialogue.js
|
//=include Dialogue.js
|
||||||
//=include History.js
|
//=include History.js
|
||||||
|
|
||||||
|
//=include ColorModule.js
|
||||||
//=include _drawLine.js
|
//=include _drawLine.js
|
||||||
//=include _tools.js
|
//=include _tools.js
|
||||||
//=include tools/*.js
|
//=include tools/*.js
|
||||||
@ -30,8 +30,6 @@
|
|||||||
|
|
||||||
/**functions**/
|
/**functions**/
|
||||||
//=include _changeZoom.js
|
//=include _changeZoom.js
|
||||||
//=include ColorModule.js
|
|
||||||
//=include _fill.js
|
|
||||||
//=include _checkerboard.js
|
//=include _checkerboard.js
|
||||||
//=include _copyPaste.js
|
//=include _copyPaste.js
|
||||||
//=include _resizeCanvas.js
|
//=include _resizeCanvas.js
|
||||||
@ -50,7 +48,6 @@
|
|||||||
|
|
||||||
/**event listeners**/
|
/**event listeners**/
|
||||||
//=include Input.js
|
//=include Input.js
|
||||||
//=include _mouseEvents.js
|
|
||||||
|
|
||||||
/**feature toggles**/
|
/**feature toggles**/
|
||||||
//=include _featureToggles.js
|
//=include _featureToggles.js
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
class EyedropperTool extends Tool {
|
||||||
|
eyedropperPreview = document.getElementById("eyedropper-preview");
|
||||||
|
selectedColor = {r:0, g:0, b:0};
|
||||||
|
|
||||||
|
constructor(name, options, switchFunction) {
|
||||||
|
super(name, options);
|
||||||
|
|
||||||
|
Events.on('click', this.mainButton, switchFunction, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onStart(mousePos) {
|
||||||
|
super.onStart(mousePos);
|
||||||
|
|
||||||
|
this.eyedropperPreview.style.display = 'block';
|
||||||
|
this.onDrag(mousePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrag(mousePos) {
|
||||||
|
super.onDrag(mousePos);
|
||||||
|
|
||||||
|
this.selectedColor = this.pickColor(mousePos);
|
||||||
|
|
||||||
|
this.eyedropperPreview.style.borderColor = '#' + Color.rgbToHex(this.selectedColor);
|
||||||
|
this.eyedropperPreview.style.left = mousePos[0] + currentLayer.canvas.offsetLeft - 30 + 'px';
|
||||||
|
this.eyedropperPreview.style.top = mousePos[1] + currentLayer.canvas.offsetTop - 30 + 'px';
|
||||||
|
|
||||||
|
const colorLightness = Math.max(this.selectedColor.r,this.selectedColor.g,this.selectedColor.b);
|
||||||
|
|
||||||
|
//for the darkest 50% of colors, change the eyedropper preview to dark mode
|
||||||
|
if (colorLightness>127) this.eyedropperPreview.classList.remove('dark');
|
||||||
|
else this.eyedropperPreview.classList.add('dark');
|
||||||
|
|
||||||
|
this.changeColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
onEnd(mousePos) {
|
||||||
|
super.onEnd(mousePos);
|
||||||
|
this.eyedropperPreview.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
changeColor() {
|
||||||
|
let colorHex = Color.rgbToHex(this.selectedColor);
|
||||||
|
ColorModule.updateCurrentColor('#' + Color.rgbToHex(this.selectedColor));
|
||||||
|
|
||||||
|
let colors = document.getElementsByClassName('color-button');
|
||||||
|
for (let i = 0; i < colors.length; i++) {
|
||||||
|
//if picked color matches this color
|
||||||
|
if (colorHex == 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 = '#' + colorHex;
|
||||||
|
}
|
||||||
|
|
||||||
|
//make color selected
|
||||||
|
colors[i].parentElement.classList.add('selected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
* make much sense to sample a colour which is hidden behind a different layer
|
||||||
|
*
|
||||||
|
* @param {*} cursorLocation The position of the cursor
|
||||||
|
*/
|
||||||
|
pickColor(cursorLocation) {
|
||||||
|
// Making sure max will take some kind of value
|
||||||
|
let max = -1;
|
||||||
|
// Using tmpColour to sample the sprite
|
||||||
|
let tmpColour;
|
||||||
|
// Returned colour
|
||||||
|
let selectedColor;
|
||||||
|
|
||||||
|
for (let i=1; i<layers.length; i++) {
|
||||||
|
// Getting the colour of the pixel in the cursorLocation
|
||||||
|
tmpColour = layers[i].context.getImageData(Math.floor(cursorLocation[0]/zoom),Math.floor(cursorLocation[1]/zoom),1,1).data;
|
||||||
|
|
||||||
|
// If it's not empty, I check if it's on the top of the previous colour
|
||||||
|
if (layers[i].canvas.style.zIndex > max || Util.isPixelEmpty(selectedColor) || selectedColor === undefined) {
|
||||||
|
max = layers[i].canvas.style.zIndex;
|
||||||
|
|
||||||
|
if (!Util.isPixelEmpty(tmpColour)) {
|
||||||
|
selectedColor = tmpColour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the final colour was empty, I return black
|
||||||
|
if (Util.isPixelEmpty(tmpColour) && selectedColor === undefined) {
|
||||||
|
selectedColor = [0, 0, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {r:selectedColor[0], g:selectedColor[1], b:selectedColor[2]};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onSelect() {
|
||||||
|
super.onSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeselect() {
|
||||||
|
super.onDeselect();
|
||||||
|
this.eyedropperPreview.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,3 @@
|
|||||||
new Tool('eyedropper', {
|
|
||||||
imageCursor: 'eyedropper',
|
|
||||||
});
|
|
||||||
|
|
||||||
new Tool('resizeline', {
|
new Tool('resizeline', {
|
||||||
cursor: 'default',
|
cursor: 'default',
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user