Added Color class
- Added Color class to make color representation and convertions more uniform - Replaced standard convertions with Color.convertion - Removed _algorithms.js, _deleteColor.js, ajax.js and the other convertion files - Fixed bug in ColorModule, moved replaceAllOfColor to ColorModule as well as deleteColor
This commit is contained in:
parent
dbffc0b9da
commit
f5807417ec
|
@ -0,0 +1,169 @@
|
|||
// OPTIMIZABLE: add a normalize function that returns the normalized colour in the current
|
||||
// format.
|
||||
class Color {
|
||||
constructor(fmt, v1, v2, v3, v4) {
|
||||
this.fmt = fmt;
|
||||
|
||||
switch (fmt) {
|
||||
case 'hsv':
|
||||
this.hsv = {h: v1, s: v2, v: v3};
|
||||
this.rgb = Color.hsvToRgb(this.hsv);
|
||||
this.hsl = Color.rgbToHsl(this.rgb);
|
||||
this.hex = Color.rgbToHex(this.rgb);
|
||||
break;
|
||||
case 'hsl':
|
||||
this.hsl = {h: v1, s: v2, l: v3};
|
||||
this.rgb = Color.hslToRgb(this.hsl);
|
||||
this.hsv = Color.rgbToHsv(this.rgb);
|
||||
this.hex = Color.rgbToHex(this.rgb);
|
||||
break;
|
||||
case 'rgb':
|
||||
this.rgb = {r: v1, g: v2, b: v3};
|
||||
this.hsl = Color.rgbToHsl(this.rgb);
|
||||
this.hsv = Color.rgbToHsv(this.rgb);
|
||||
this.hex = Color.rgbToHex(this.rgb);
|
||||
break;
|
||||
case 'hex':
|
||||
this.hex = v1;
|
||||
this.rgb = Color.hexToRgb(this.hex);
|
||||
this.hsl = Color.rgbToHsl(this.rgb);
|
||||
this.hsv = Color.rgbToHsv(this.rgb);
|
||||
break;
|
||||
default:
|
||||
console.error("Unsupported color mode " + fmt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static hexToRgb(hex, divisor) {
|
||||
//if divisor isn't set, set it to one (so it has no effect)
|
||||
divisor = divisor || 1;
|
||||
//split given hex code into array of 3 values
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim());
|
||||
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16)/divisor,
|
||||
g: parseInt(result[2], 16)/divisor,
|
||||
b: parseInt(result[3], 16)/divisor
|
||||
} : null;
|
||||
}
|
||||
static rgbToHex(rgb) {
|
||||
//convert a decimal number to 2-digit hex
|
||||
function componentToHex (c) {
|
||||
var hex = c.toString(16);
|
||||
return hex.length == 1 ? "0" + hex : hex;
|
||||
}
|
||||
|
||||
return componentToHex(rgb.r) + componentToHex(rgb.g) + componentToHex(rgb.b);
|
||||
}
|
||||
|
||||
static hslToRgb(hsl) {
|
||||
var r, g, b;
|
||||
var h = hsl.h, s = hsl.s, l = hsl.l;
|
||||
|
||||
h /= 255;
|
||||
s /= 255;
|
||||
l /= 255;
|
||||
|
||||
if(s == 0){
|
||||
r = g = b = l; // achromatic
|
||||
}else{
|
||||
var hue2rgb = function hue2rgb(p, q, t){
|
||||
if(t < 0) t += 1;
|
||||
if(t > 1) t -= 1;
|
||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||
if(t < 1/2) return q;
|
||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return {
|
||||
r:Math.round(r * 255),
|
||||
g:Math.round(g * 255),
|
||||
b:Math.round(b * 255)
|
||||
};
|
||||
}
|
||||
static rgbToHsl(rgb) {
|
||||
var r, g, b;
|
||||
r = rgb.r; g = rgb.g; b = rgb.b;
|
||||
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var hue, saturation, luminosity = (max + min) / 2;
|
||||
|
||||
if(max == min){
|
||||
hue = saturation = 0; // achromatic
|
||||
}else{
|
||||
var d = max - min;
|
||||
saturation = luminosity > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch(max){
|
||||
case r: hue = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: hue = (b - r) / d + 2; break;
|
||||
case b: hue = (r - g) / d + 4; break;
|
||||
}
|
||||
hue /= 6;
|
||||
}
|
||||
|
||||
return {h:hue, s:saturation, l:luminosity};
|
||||
}
|
||||
|
||||
static hsvToRgb(hsv) {
|
||||
var r, g, b, h, s, v;
|
||||
h = hsv.h; s = hsv.s; v = hsv.v;
|
||||
|
||||
h /= 360;
|
||||
s /= 100;
|
||||
v /= 100;
|
||||
|
||||
var i = Math.floor(h * 6);
|
||||
var f = h * 6 - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - f * s);
|
||||
var t = v * (1 - (1 - f) * s);
|
||||
|
||||
switch (i % 6) {
|
||||
case 0: r = v, g = t, b = p; break;
|
||||
case 1: r = q, g = v, b = p; break;
|
||||
case 2: r = p, g = v, b = t; break;
|
||||
case 3: r = p, g = q, b = v; break;
|
||||
case 4: r = t, g = p, b = v; break;
|
||||
case 5: r = v, g = p, b = q; break;
|
||||
}
|
||||
|
||||
return {r: r * 255, g: g * 255, b: b * 255 };
|
||||
}
|
||||
static rgbToHsv(rgb) {
|
||||
let r = rgb.r, g = rgb.g, b = rgb.b;
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
|
||||
let max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
let myH, myS, myV = max;
|
||||
|
||||
let d = max - min;
|
||||
myS = max == 0 ? 0 : d / max;
|
||||
|
||||
if (max == min) {
|
||||
myH = 0; // achromatic
|
||||
}
|
||||
else {
|
||||
switch (max) {
|
||||
case r: myH = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: myH = (b - r) / d + 2; break;
|
||||
case b: myH = (r - g) / d + 4; break;
|
||||
}
|
||||
|
||||
myH /= 6;
|
||||
}
|
||||
|
||||
return {h: myH * 360, s: myS * 100, v: myV * 100};
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
const ColorModule = (() => {
|
||||
const currentPalette = [];
|
||||
const coloursList = document.getElementById("palette-list");
|
||||
|
||||
|
||||
console.info("Initialized Color Module..");
|
||||
document.getElementById('jscolor-hex-input').addEventListener('change',colorChanged, false);
|
||||
|
@ -22,10 +21,12 @@ const ColorModule = (() => {
|
|||
|
||||
// Changes all of one color to another after being changed from color picker
|
||||
function colorChanged(colorHexElement) {
|
||||
console.log("Clicked:");
|
||||
console.log(colorHexElement);
|
||||
// Get old and new colors from the element
|
||||
const hexElement = colorHexElement.target;
|
||||
const hexElementValue = hexElement.value;
|
||||
const newColor = hexToRgb(hexElementValue);
|
||||
const newColor = Color.hexToRgb(hexElementValue);
|
||||
const oldColor = hexElement.oldColor;
|
||||
|
||||
//if the color is not a valid hex color, exit this function and do nothing
|
||||
|
@ -36,7 +37,7 @@ const ColorModule = (() => {
|
|||
newColor.a = 255;
|
||||
|
||||
//save undo state
|
||||
new HistoryStateEditColor(hexElementValue.toLowerCase(), rgbToHex(oldColor));
|
||||
new HistoryStateEditColor(hexElementValue.toLowerCase(), Color.rgbToHex(oldColor));
|
||||
|
||||
//get the currently selected color
|
||||
const currentlyEditedColor = document.getElementsByClassName('jscolor-active')[0];
|
||||
|
@ -73,7 +74,7 @@ const ColorModule = (() => {
|
|||
|
||||
currentlyEditedColor.firstChild.jscolor.fromString(newColorHex);
|
||||
|
||||
replaceAllOfColor(oldColor, newColor);
|
||||
ColorModule.replaceAllOfColor(oldColor, newColor);
|
||||
|
||||
//set new old color to changed color
|
||||
hexElement.oldColor = newColor;
|
||||
|
@ -82,7 +83,7 @@ const ColorModule = (() => {
|
|||
//if this is the current color, update the drawing color
|
||||
if (hexElement.colorElement.parentElement.classList.contains('selected')) {
|
||||
for (let i=1; i<layers.length - nAppLayers; i++) {
|
||||
layers[i].context.fillStyle = '#'+ rgbToHex(newColor.r,newColor.g,newColor.b);
|
||||
layers[i].context.fillStyle = '#'+ Color.rgbToHex(newColor);
|
||||
}
|
||||
currentGlobalColor = newColor;
|
||||
}
|
||||
|
@ -90,11 +91,7 @@ const ColorModule = (() => {
|
|||
|
||||
function addColorButtonEvent() {
|
||||
//generate random color
|
||||
const hue = Math.floor(Math.random()*255);
|
||||
const sat = 130+Math.floor(Math.random()*100);
|
||||
const lit = 70+Math.floor(Math.random()*100);
|
||||
const newColorRgb = hslToRgb(hue,sat,lit);
|
||||
const newColor = rgbToHex(newColorRgb.r,newColorRgb.g,newColorRgb.b);
|
||||
const newColor = new Color("hsl", Math.floor(Math.random()*255), 130+Math.floor(Math.random()*100), 70+Math.floor(Math.random()*100)).hex;
|
||||
|
||||
//remove current color selection
|
||||
document.querySelector('#colors-menu li.selected').classList.remove('selected');
|
||||
|
@ -183,13 +180,13 @@ const ColorModule = (() => {
|
|||
newEditButton = editButtonTemplate.cloneNode(true);
|
||||
listItem.appendChild(newEditButton);
|
||||
|
||||
newEditButton.addEventListener('click', (e,button) => {
|
||||
newEditButton.addEventListener('click', () => {
|
||||
//hide edit button
|
||||
button.parentElement.lastChild.classList.add('hidden');
|
||||
newEditButton.parentElement.lastChild.classList.add('hidden');
|
||||
|
||||
//show jscolor picker, if basic mode is enabled
|
||||
if (pixelEditorMode == 'Basic')
|
||||
button.parentElement.firstChild.jscolor.show();
|
||||
newEditButton.parentElement.firstChild.jscolor.show();
|
||||
else
|
||||
showDialogue("palette-block", false);
|
||||
});
|
||||
|
@ -197,9 +194,100 @@ const ColorModule = (() => {
|
|||
return listItem;
|
||||
}
|
||||
|
||||
function deleteColor (color) {
|
||||
const logStyle = 'background: #913939; color: white; padding: 5px;';
|
||||
|
||||
//if color is a string, then find the corresponding button
|
||||
if (typeof color === 'string') {
|
||||
//console.log('trying to find ',color);
|
||||
//get all colors in palette
|
||||
colors = document.getElementsByClassName('color-button');
|
||||
|
||||
//loop through colors
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
//console.log(color,'=',colors[i].jscolor.toString());
|
||||
|
||||
if (color == colors[i].jscolor.toString()) {
|
||||
//set color to the color button
|
||||
color = colors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if the color wasn't found
|
||||
if (typeof color === 'string') {
|
||||
//exit function
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//hide color picker
|
||||
color.jscolor.hide();
|
||||
|
||||
//find lightest color in palette
|
||||
var colors = document.getElementsByClassName('color-button');
|
||||
var lightestColor = [0,null];
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
|
||||
//get colors lightness
|
||||
var lightness = Color.rgbToHsl(colors[i].jscolor.toRgb()).l;
|
||||
|
||||
//if not the color we're deleting
|
||||
if (colors[i] != color) {
|
||||
|
||||
//if lighter than the current lightest, set as the new lightest
|
||||
if (lightness > lightestColor[0]) {
|
||||
lightestColor[0] = lightness;
|
||||
lightestColor[1] = colors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//replace deleted color with lightest color
|
||||
ColorModule.replaceAllOfColor(color.jscolor.toString(),lightestColor[1].jscolor.toString());
|
||||
|
||||
//if the color you are deleting is the currently selected color
|
||||
if (color.parentElement.classList.contains('selected')) {
|
||||
//set current color TO LIGHTEST COLOR
|
||||
lightestColor[1].parentElement.classList.add('selected');
|
||||
currentLayer.context.fillStyle = '#'+lightestColor[1].jscolor.toString();
|
||||
}
|
||||
|
||||
//delete the element
|
||||
colorsMenu.removeChild(color.parentElement);
|
||||
}
|
||||
|
||||
//replaces all of a single color on the canvas with a different color
|
||||
//input two rgb color objects {r:0,g:0,b:0}
|
||||
function replaceAllOfColor (oldColor, newColor) {
|
||||
|
||||
//convert strings to objects if nessesary
|
||||
if (typeof oldColor === 'string') oldColor = Color.hexToRgb(oldColor);
|
||||
if (typeof newColor === 'string') newColor = Color.hexToRgb(newColor);
|
||||
|
||||
//create temporary image from canvas to search through
|
||||
var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
|
||||
|
||||
//loop through all pixels
|
||||
for (var i=0;i<tempImage.data.length;i+=4) {
|
||||
//check if pixel matches old color
|
||||
if(tempImage.data[i]==oldColor.r && tempImage.data[i+1]==oldColor.g && tempImage.data[i+2]==oldColor.b){
|
||||
//change to new color
|
||||
tempImage.data[i]=newColor.r;
|
||||
tempImage.data[i+1]=newColor.g;
|
||||
tempImage.data[i+2]=newColor.b;
|
||||
}
|
||||
}
|
||||
|
||||
//put temp image back onto canvas
|
||||
currentLayer.context.putImageData(tempImage,0,0);
|
||||
}
|
||||
|
||||
return {
|
||||
currentPalette,
|
||||
addColor,
|
||||
deleteColor,
|
||||
replaceAllOfColor,
|
||||
AddToSimplePalette
|
||||
}
|
||||
})();
|
||||
|
|
16
js/Util.js
16
js/Util.js
|
@ -1,5 +1,11 @@
|
|||
// Acts as a public static class
|
||||
class Util {
|
||||
/** Returns elementOrElementId if the argument is already an element, otherwise it finds
|
||||
* the element by its ID (given by the argument) and returns it
|
||||
*
|
||||
* @param {*} elementOrElementId The element to return, or the ID of the element to return
|
||||
* @returns The desired element
|
||||
*/
|
||||
static getElement(elementOrElementId) {
|
||||
if (typeof(elementOrElementId) == "object") {
|
||||
return elementOrElementId;
|
||||
|
@ -11,25 +17,29 @@ class Util {
|
|||
console.log("Type not supported: " + typeof(elementOrElementId));
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the text content of the element with ID elementId
|
||||
static getText(elementId) {
|
||||
return Util.getElement(elementId).textContent;
|
||||
}
|
||||
|
||||
// Sets the text content of the element with ID elementId
|
||||
static setText(elementId, text) {
|
||||
Util.getElement(elementId).textContent = text;
|
||||
}
|
||||
|
||||
// Gets the value of the element with ID elementId
|
||||
static getValue(elementId) {
|
||||
return Util.getElement(elementId).value;
|
||||
}
|
||||
|
||||
// Sets the value of the element with ID elementId
|
||||
static setValue(elementId, value) {
|
||||
Util.getElement(elementId).value = value;
|
||||
}
|
||||
|
||||
//add class .selected to specified element
|
||||
static select(elementId) {
|
||||
Util.getElement(elementId).classList.add('selected');
|
||||
}
|
||||
|
||||
//remove .selected class from specified element
|
||||
static deselect(elementId) {
|
||||
Util.getElement(elementId).classList.remove('selected');
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
// CONSTS
|
||||
|
||||
// Degrees to radiants
|
||||
let degreesToRad = Math.PI / 180;
|
||||
// I'm pretty sure that precision is necessary
|
||||
let referenceWhite = {x: 95.05, y: 100, z: 108.89999999999999};
|
||||
|
||||
/**********************SECTION: COLOUR CONVERSIONS****************************** */
|
||||
|
||||
/**
|
||||
* Converts an HSL color value to RGB. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes h, s, and l are contained in the set [0, 1] and
|
||||
* returns r, g, and b in the set [0, 255].
|
||||
*
|
||||
* @param {number} h The hue
|
||||
* @param {number} s The saturation
|
||||
* @param {number} l The lightness
|
||||
* @return {Array} The RGB representation
|
||||
*/
|
||||
function cpHslToRgb(h, s, l){
|
||||
var r, g, b;
|
||||
|
||||
h /= 360;
|
||||
s /= 100;
|
||||
l /= 100;
|
||||
|
||||
if(s == 0){
|
||||
r = g = b = l; // achromatic
|
||||
}else{
|
||||
var hue2rgb = function hue2rgb(p, q, t){
|
||||
if(t < 0) t += 1;
|
||||
if(t > 1) t -= 1;
|
||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||
if(t < 1/2) return q;
|
||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
||||
}
|
||||
|
||||
function hsvToRgb(h, s, v) {
|
||||
var r, g, b;
|
||||
|
||||
h /= 360;
|
||||
s /= 100;
|
||||
v /= 100;
|
||||
var i = Math.floor(h * 6);
|
||||
var f = h * 6 - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - f * s);
|
||||
var t = v * (1 - (1 - f) * s);
|
||||
|
||||
switch (i % 6) {
|
||||
case 0: r = v, g = t, b = p; break;
|
||||
case 1: r = q, g = v, b = p; break;
|
||||
case 2: r = p, g = v, b = t; break;
|
||||
case 3: r = p, g = q, b = v; break;
|
||||
case 4: r = t, g = p, b = v; break;
|
||||
case 5: r = v, g = p, b = q; break;
|
||||
}
|
||||
|
||||
return [ r * 255, g * 255, b * 255 ];
|
||||
}
|
||||
|
||||
function hslToHex(h, s, l) {
|
||||
h /= 360;
|
||||
s /= 100;
|
||||
l /= 100;
|
||||
let r, g, b;
|
||||
if (s === 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
const hue2rgb = (p, q, t) => {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
const toHex = x => {
|
||||
const hex = Math.round(x * 255).toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
};
|
||||
|
||||
return `${toHex(r)}${toHex(g)}${toHex(b)}`;
|
||||
}
|
||||
|
||||
function rgbToHsl(col) {
|
||||
let r = col.r;
|
||||
let g = col.g;
|
||||
let b = col.b;
|
||||
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
|
||||
let max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
let myH, myS, myL = (max + min) / 2;
|
||||
|
||||
if (max == min) {
|
||||
myH = myS = 0; // achromatic
|
||||
}
|
||||
else {
|
||||
let d = max - min;
|
||||
myS = myL > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
switch (max) {
|
||||
case r: myH = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: myH = (b - r) / d + 2; break;
|
||||
case b: myH = (r - g) / d + 4; break;
|
||||
}
|
||||
|
||||
myH /= 6;
|
||||
}
|
||||
|
||||
return {h: myH, s: myS, l: myL };
|
||||
}
|
||||
|
||||
function rgbToHsv(col) {
|
||||
let r = col.r;
|
||||
let g = col.g;
|
||||
let b = col.b;
|
||||
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
|
||||
let max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
let myH, myS, myV = max;
|
||||
|
||||
let d = max - min;
|
||||
myS = max == 0 ? 0 : d / max;
|
||||
|
||||
if (max == min) {
|
||||
myH = 0; // achromatic
|
||||
}
|
||||
else {
|
||||
switch (max) {
|
||||
case r: myH = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: myH = (b - r) / d + 2; break;
|
||||
case b: myH = (r - g) / d + 4; break;
|
||||
}
|
||||
|
||||
myH /= 6;
|
||||
}
|
||||
|
||||
return {h: myH, s: myS, v: myV};
|
||||
}
|
||||
|
||||
function RGBtoCIELAB(rgbColour) {
|
||||
// Convert to XYZ first via matrix transformation
|
||||
let x = 0.412453 * rgbColour.r + 0.357580 * rgbColour.g + 0.180423 * rgbColour.b;
|
||||
let y = 0.212671 * rgbColour.r + 0.715160 * rgbColour.g + 0.072169 * rgbColour.b;
|
||||
let z = 0.019334 * rgbColour.r + 0.119193 * rgbColour.g + 0.950227 * rgbColour.b;
|
||||
|
||||
let xFunc = CIELABconvF(x / referenceWhite.x);
|
||||
let yFunc = CIELABconvF(y / referenceWhite.y);
|
||||
let zFunc = CIELABconvF(z / referenceWhite.z);
|
||||
|
||||
let myL = 116 * yFunc - 16;
|
||||
let myA = 500 * (xFunc - yFunc);
|
||||
let myB = 200 * (yFunc - zFunc);
|
||||
|
||||
return {l: myL, a: myA, b: myB};
|
||||
|
||||
}
|
||||
function CIELABconvF(value) {
|
||||
if (value > Math.pow(6/29, 3)) {
|
||||
return Math.cbrt(value);
|
||||
}
|
||||
|
||||
return 1/3 * Math.pow(6/29, 2) * value + 4/29;
|
||||
}
|
|
@ -71,26 +71,12 @@ function updateSliderValue (sliderIndex, updateMini = true) {
|
|||
// Update preview colour
|
||||
// get slider values
|
||||
sliderValues = getSlidersValues();
|
||||
|
||||
// Generate preview colour
|
||||
switch (currentPickerMode) {
|
||||
case 'rgb':
|
||||
hexColour = rgbToHex(sliderValues[0], sliderValues[1], sliderValues[2]);
|
||||
break;
|
||||
case 'hsv':
|
||||
let tmpRgb = hsvToRgb(sliderValues[0], sliderValues[1], sliderValues[2]);
|
||||
hexColour = rgbToHex(parseInt(tmpRgb[0]), parseInt(tmpRgb[1]), parseInt(tmpRgb[2]));
|
||||
break;
|
||||
case 'hsl':
|
||||
hexColour = hslToHex(sliderValues[0], sliderValues[1], sliderValues[2]);
|
||||
break;
|
||||
default:
|
||||
console.log("wtf select a decent picker mode");
|
||||
return;
|
||||
}
|
||||
hexColour = new Color(currentPickerMode, sliderValues[0], sliderValues[1], sliderValues[2]);
|
||||
|
||||
// Update preview colour div
|
||||
colourPreview.style.backgroundColor = '#' + hexColour;
|
||||
colourValue.value = '#' + hexColour;
|
||||
colourPreview.style.backgroundColor = '#' + hexColour.hex;
|
||||
colourValue.value = '#' + hexColour.hex;
|
||||
|
||||
// Update sliders background
|
||||
// there's no other way than creating a custom css file, appending it to the head and
|
||||
|
@ -270,6 +256,7 @@ function changePickerMode(target, newMode) {
|
|||
let colArray;
|
||||
let rgbTmp;
|
||||
let hexColour = colourValue.value.replace('#', '');
|
||||
let currColor = new Color("hex", hexColour);
|
||||
|
||||
currentPickerMode = newMode;
|
||||
document.getElementsByClassName("cp-selected-mode")[0].classList.remove("cp-selected-mode");
|
||||
|
@ -309,30 +296,16 @@ function changePickerMode(target, newMode) {
|
|||
// Putting the current colour in the new slider
|
||||
switch(currentPickerMode) {
|
||||
case 'rgb':
|
||||
colArray = hexToRgb(hexColour);
|
||||
colArray = currColor.rgb;
|
||||
colArray = [colArray.r, colArray.g, colArray.b];
|
||||
break;
|
||||
case 'hsv':
|
||||
rgbTmp = hexToRgb(hexColour);
|
||||
colArray = rgbToHsv(rgbTmp);
|
||||
|
||||
colArray.h *= 360;
|
||||
colArray.s *= 100;
|
||||
colArray.v *= 100;
|
||||
|
||||
colArray = currColor.hsv;
|
||||
colArray = [colArray.h, colArray.s, colArray.v];
|
||||
|
||||
break;
|
||||
case 'hsl':
|
||||
rgbTmp = hexToRgb(hexColour);
|
||||
colArray = rgbToHsl(rgbTmp);
|
||||
|
||||
colArray.h *= 360;
|
||||
colArray.s *= 100;
|
||||
colArray.l *= 100;
|
||||
|
||||
colArray = currColor.hsl;
|
||||
colArray = [colArray.h, colArray.s, colArray.l];
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -385,14 +358,14 @@ function movePickerIcon(event) {
|
|||
|
||||
// Updates the main sliders given a hex value computed with the minipicker
|
||||
function updateSlidersByHex(hex, updateMini = true) {
|
||||
let colour;
|
||||
let colour = new Color("hex", hex);
|
||||
let mySliders = [sliders[0].getElementsByTagName("input")[0],
|
||||
sliders[1].getElementsByTagName("input")[0],
|
||||
sliders[2].getElementsByTagName("input")[0]];
|
||||
|
||||
switch (currentPickerMode) {
|
||||
case 'rgb':
|
||||
colour = hexToRgb(hex);
|
||||
colour = colour.rgb;
|
||||
|
||||
mySliders[0].value = colour.r;
|
||||
mySliders[1].value = colour.g;
|
||||
|
@ -400,7 +373,7 @@ function updateSlidersByHex(hex, updateMini = true) {
|
|||
|
||||
break;
|
||||
case 'hsv':
|
||||
colour = rgbToHsv(hexToRgb(hex));
|
||||
colour = colour.hsv;
|
||||
|
||||
mySliders[0].value = colour.h * 360;
|
||||
mySliders[1].value = colour.s * 100;
|
||||
|
@ -408,7 +381,7 @@ function updateSlidersByHex(hex, updateMini = true) {
|
|||
|
||||
break;
|
||||
case 'hsl':
|
||||
colour = rgbToHsl(hexToRgb(hex));
|
||||
colour = colour.hsl;
|
||||
|
||||
mySliders[0].value = colour.h * 360;
|
||||
mySliders[1].value = colour.s * 100;
|
||||
|
@ -445,7 +418,7 @@ function getCursorPosMinipicker(e) {
|
|||
// Updates the minipicker given a hex computed by the main sliders
|
||||
// Moves the cursor
|
||||
function updatePickerByHex(hex) {
|
||||
let hsv = rgbToHsv(hexToRgb(hex));
|
||||
let hsv = new Color("hex", hex).hsv;
|
||||
let xPos = miniPickerCanvas.width * hsv.h - 8;
|
||||
let yPos = miniPickerCanvas.height * hsv.s + 8;
|
||||
|
||||
|
@ -471,15 +444,15 @@ function updatePickerByHex(hex) {
|
|||
|
||||
// Fired when the value of the minislider changes: updates the spectrum gradient and the hex colour
|
||||
function miniSliderInput(event) {
|
||||
let newHex;
|
||||
let newHsv = rgbToHsv(hexToRgb(getMiniPickerColour()));
|
||||
let currColor = new Color("hex", getMiniPickerColour());
|
||||
let newHex = currColor.hex;
|
||||
let newHsv = currColor.hsv;
|
||||
let rgb;
|
||||
|
||||
// Adding slider value to value
|
||||
newHsv.v = parseInt(event.target.value);
|
||||
// Updating hex
|
||||
rgb = hsvToRgb(newHsv.h * 360, newHsv.s * 100, newHsv.v);
|
||||
newHex = rgbToHex(Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2]));
|
||||
newHex = Color.rgbToHex(Color.hsvToRgb(newHsv));
|
||||
|
||||
colourValue.value = newHex;
|
||||
|
||||
|
@ -504,20 +477,17 @@ function updateMiniPickerColour() {
|
|||
|
||||
// Returns the current colour of the minipicker
|
||||
function getMiniPickerColour() {
|
||||
let hex;
|
||||
let pickedColour;
|
||||
|
||||
pickedColour = miniPickerCanvas.getContext('2d').getImageData(currPickerIconPos[0][0] + 8,
|
||||
currPickerIconPos[0][1] + 8, 1, 1).data;
|
||||
|
||||
hex = rgbToHex(pickedColour[0], pickedColour[1], pickedColour[2]);
|
||||
|
||||
return hex;
|
||||
return new Color("rgb", pickedColour[0], pickedColour[1], pickedColour[2]).hex;
|
||||
}
|
||||
|
||||
// Update the background gradient of the slider in the minipicker
|
||||
function updateMiniSlider(hex) {
|
||||
let rgb = hexToRgb(hex);
|
||||
let rgb = Color.hexToRgb(hex);
|
||||
|
||||
styles[1] = "input[type=range]#cp-minipicker-slider::-webkit-slider-runnable-track { background: rgb(2,0,36);";
|
||||
styles[1] += "background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(0,0,0,1) 0%, " +
|
||||
|
@ -530,11 +500,9 @@ function updateMiniSlider(hex) {
|
|||
// Updates the gradient of the spectrum canvas in the minipicker
|
||||
function updateMiniPickerSpectrum() {
|
||||
let ctx = miniPickerCanvas.getContext('2d');
|
||||
let hsv = rgbToHsv(hexToRgb(colourValue.value));
|
||||
let hsv = new Color("hex", colourValue.value).hsv;
|
||||
let tmp;
|
||||
let white = {h:hsv.h * 360, s:0, v: parseInt(miniPickerSlider.value)};
|
||||
|
||||
white = hsvToRgb(white.h, white.s, white.v);
|
||||
let white = new Color("hsv", hsv.h, 0, parseInt(miniPickerSlider.value)).rgb;
|
||||
|
||||
ctx.clearRect(0, 0, miniPickerCanvas.width, miniPickerCanvas.height);
|
||||
|
||||
|
@ -542,20 +510,16 @@ function updateMiniPickerSpectrum() {
|
|||
var hGrad = ctx.createLinearGradient(0, 0, miniPickerCanvas.width, 0);
|
||||
|
||||
for (let i=0; i<7; i++) {
|
||||
tmp = hsvToRgb(60 * i, 100, hsv.v * 100);
|
||||
hGrad.addColorStop(i / 6, '#' + rgbToHex(Math.round(tmp[0]), Math.round(tmp[1]), Math.round(tmp[2])));
|
||||
let stopHex = new Color("hsv", 60*i, 100, hsv.v);
|
||||
hGrad.addColorStop(i / 6, '#' + stopHex.hex);
|
||||
}
|
||||
ctx.fillStyle = hGrad;
|
||||
ctx.fillRect(0, 0, miniPickerCanvas.width, miniPickerCanvas.height);
|
||||
|
||||
// Drawing sat / lum
|
||||
var vGrad = ctx.createLinearGradient(0, 0, 0, miniPickerCanvas.height);
|
||||
vGrad.addColorStop(0, 'rgba(' + white[0] +',' + white[1] + ',' + white[2] + ',0)');
|
||||
/*
|
||||
vGrad.addColorStop(0.1, 'rgba(255,255,255,0)');
|
||||
vGrad.addColorStop(0.9, 'rgba(255,255,255,1)');
|
||||
*/
|
||||
vGrad.addColorStop(1, 'rgba(' + white[0] +',' + white[1] + ',' + white[2] + ',1)');
|
||||
vGrad.addColorStop(0, 'rgba(' + white.r +',' + white.g + ',' + white.b + ',0)');
|
||||
vGrad.addColorStop(1, 'rgba(' + white.r +',' + white.g + ',' + white.b + ',1)');
|
||||
|
||||
ctx.fillStyle = vGrad;
|
||||
ctx.fillRect(0, 0, miniPickerCanvas.width, miniPickerCanvas.height);
|
||||
|
@ -649,89 +613,77 @@ function changePickingMode(event, newMode) {
|
|||
}
|
||||
|
||||
function updateOtherIcons() {
|
||||
let currentColorHex = colourValue.value;
|
||||
let currentColourHsv = rgbToHsv(hexToRgb(currentColorHex));
|
||||
let newColourHsv = {h:currentColourHsv.h, s:currentColourHsv.s, v:currentColourHsv.v};
|
||||
let currentColorHex = new Color("hex", colourValue.value).hex;
|
||||
let currentColourHsv = new Color("hex", currentColorHex).hsv;
|
||||
let newColourHsv;
|
||||
let newColourHexes = ['', '', ''];
|
||||
let tmpRgb;
|
||||
|
||||
// Salvo tutti i
|
||||
|
||||
switch (currentPickingMode)
|
||||
{
|
||||
case 'mono':
|
||||
break;
|
||||
case 'analog':
|
||||
// First colour
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 40) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", ((currentColourHsv.h + 40) % 360), currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[0] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
newColourHexes[0] = newColourHsv.hex;
|
||||
|
||||
// Second colour
|
||||
newColourHsv.h = (((currentColourHsv.h*360 - 40) % 360) / 360);
|
||||
if (newColourHsv.h < 0) {
|
||||
newColourHsv.h += 1;
|
||||
}
|
||||
newColourHsv.h = new Color("hsv", ((currentColourHsv.h + 320) % 360), currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[2][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[2][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[2][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[1] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
|
||||
newColourHexes[1] = newColourHsv.hex;
|
||||
break;
|
||||
case 'cmpt':
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 180) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", ((currentColourHsv.h + 180) % 360), currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[0] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
newColourHexes[0] = newColourHsv.hex;
|
||||
break;
|
||||
case 'tri':
|
||||
for (let i=1; i< 3; i++) {
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 120*i) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", (currentColourHsv.h + 120*i) % 360, currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[i][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[i][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[i - 1] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
currPickerIconPos[i][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[i][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
newColourHexes[i - 1] = newColourHsv.hex;
|
||||
}
|
||||
|
||||
break
|
||||
case 'scmpt':
|
||||
// First colour
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 210) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", (currentColourHsv.h + 210) % 360, currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[0] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
currPickerIconPos[1][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[1][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
newColourHexes[0] = newColourHsv.hex;
|
||||
|
||||
// Second colour
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 150) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", (currentColourHsv.h + 150) % 360, currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[2][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[2][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[1] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
currPickerIconPos[2][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[2][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
newColourHexes[1] = newColourHsv.hex;
|
||||
break;
|
||||
case 'tetra':
|
||||
for (let i=1; i< 4; i++) {
|
||||
newColourHsv.h = (((currentColourHsv.h*360 + 90*i) % 360) / 360);
|
||||
newColourHsv = new Color("hsv", (currentColourHsv.h + 90*i) % 360, currentColourHsv.s, currentColourHsv.v);
|
||||
|
||||
currPickerIconPos[i][0] = miniPickerCanvas.width * newColourHsv.h - 8;
|
||||
currPickerIconPos[i][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.s + 8);
|
||||
|
||||
tmpRgb = hsvToRgb(newColourHsv.h*360, newColourHsv.s*100, newColourHsv.v*100);
|
||||
newColourHexes[i - 1] = rgbToHex(Math.round(tmpRgb[0]), Math.round(tmpRgb[1]), Math.round(tmpRgb[2]));
|
||||
currPickerIconPos[i][0] = miniPickerCanvas.width * newColourHsv.hsv.h/360 - 8;
|
||||
currPickerIconPos[i][1] = miniPickerCanvas.height - (miniPickerCanvas.height * newColourHsv.hsv.s/100 + 8);
|
||||
|
||||
newColourHexes[i - 1] = newColourHsv.hex;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -14,22 +14,22 @@ function createColorPalette(paletteColors, deletePreviousPalette = true) {
|
|||
}
|
||||
}
|
||||
|
||||
var lightestColor = '#000000';
|
||||
var darkestColor = '#ffffff';
|
||||
var lightestColor = new Color("hex", '#000000');
|
||||
var darkestColor = new Color("hex", '#ffffff');
|
||||
|
||||
// Adding all the colours in the array
|
||||
for (var i = 0; i < paletteColors.length; i++) {
|
||||
var newColor = paletteColors[i];
|
||||
var newColorElement = ColorModule.addColor(newColor);
|
||||
var newColor = new Color("hex", paletteColors[i]);
|
||||
var newColorElement = ColorModule.addColor(newColor.hex);
|
||||
|
||||
var newColorHex = hexToRgb(newColor);
|
||||
var newColRgb = newColor.rgb;
|
||||
|
||||
var lightestColorHex = hexToRgb(lightestColor);
|
||||
if (newColorHex.r + newColorHex.g + newColorHex.b > lightestColorHex.r + lightestColorHex.g + lightestColorHex.b)
|
||||
var lightestColorRgb = lightestColor.rgb;
|
||||
if (newColRgb.r + newColRgb.g + newColRgb.b > lightestColorRgb.r + lightestColorRgb.g + lightestColorRgb.b)
|
||||
lightestColor = newColor;
|
||||
|
||||
var darkestColorHex = hexToRgb(darkestColor);
|
||||
if (newColorHex.r + newColorHex.g + newColorHex.b < darkestColorHex.r + darkestColorHex.g + darkestColorHex.b) {
|
||||
var darkestColorRgb = darkestColor.rgb;
|
||||
if (newColRgb.r + newColRgb.g + newColRgb.b < darkestColorRgb.r + darkestColorRgb.g + darkestColorRgb.b) {
|
||||
|
||||
//remove current color selection
|
||||
var selectedColor = document.querySelector('#colors-menu li.selected');
|
||||
|
@ -37,16 +37,15 @@ function createColorPalette(paletteColors, deletePreviousPalette = true) {
|
|||
|
||||
//set as current color
|
||||
newColorElement.classList.add('selected');
|
||||
|
||||
darkestColor = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
//prepend # if not present
|
||||
if (!darkestColor.includes('#')) darkestColor = '#' + darkestColor;
|
||||
if (!darkestColor.hex.includes('#')) darkestColor.hex = '#' + darkestColor.hex;
|
||||
|
||||
//set as current color
|
||||
currentLayer.context.fillStyle = darkestColor;
|
||||
currentLayer.context.fillStyle = darkestColor.hex;
|
||||
}
|
||||
|
||||
/** Creates the palette with the colours used in all the layers
|
||||
|
@ -65,7 +64,7 @@ function createPaletteFromLayers() {
|
|||
let color = imageData[j]+','+imageData[j + 1]+','+imageData[j + 2];
|
||||
|
||||
if (!colors[color]) {
|
||||
colors[color] = {r:imageData[j],g:imageData[j + 1],b:imageData[j + 2]};
|
||||
colors[color] = new Color("rgb", imageData[j], imageData[j + 1], imageData[j + 2]).rgb;
|
||||
|
||||
//don't allow more than 256 colors to be added
|
||||
if (Object.keys(colors).length >= settings.maxColorsOnImportedImage) {
|
||||
|
@ -82,7 +81,7 @@ function createPaletteFromLayers() {
|
|||
let colorPaletteArray = [];
|
||||
for (let color in colors) {
|
||||
if (colors.hasOwnProperty(color)) {
|
||||
colorPaletteArray.push('#'+rgbToHex(colors[color]));
|
||||
colorPaletteArray.push('#'+Color.rgbToHex(colors[color]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
|
||||
|
||||
//called when the delete button is pressed on color picker
|
||||
//input color button or hex string
|
||||
function deleteColor (color) {
|
||||
const logStyle = 'background: #913939; color: white; padding: 5px;';
|
||||
|
||||
//console.log('%c'+'deleting color', logStyle);
|
||||
|
||||
//if color is a string, then find the corresponding button
|
||||
if (typeof color === 'string') {
|
||||
//console.log('trying to find ',color);
|
||||
//get all colors in palette
|
||||
colors = document.getElementsByClassName('color-button');
|
||||
|
||||
//loop through colors
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
//console.log(color,'=',colors[i].jscolor.toString());
|
||||
|
||||
if (color == colors[i].jscolor.toString()) {
|
||||
//console.log('match');
|
||||
//set color to the color button
|
||||
color = colors[i];
|
||||
//console.log('found color', color);
|
||||
|
||||
//exit loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if the color wasn't found
|
||||
if (typeof color === 'string') {
|
||||
//console.log('color not found');
|
||||
//exit function
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//hide color picker
|
||||
color.jscolor.hide();
|
||||
|
||||
|
||||
//find lightest color in palette
|
||||
var colors = document.getElementsByClassName('color-button');
|
||||
var lightestColor = [0,null];
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
|
||||
//get colors lightness
|
||||
var lightness = rgbToHsl(colors[i].jscolor.toRgb()).l;
|
||||
//console.log('%c'+lightness, logStyle)
|
||||
|
||||
//if not the color we're deleting
|
||||
if (colors[i] != color) {
|
||||
|
||||
//if lighter than the current lightest, set as the new lightest
|
||||
if (lightness > lightestColor[0]) {
|
||||
lightestColor[0] = lightness;
|
||||
lightestColor[1] = colors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//console.log('%c'+'replacing with lightest color: '+lightestColor[1].jscolor.toString(), logStyle)
|
||||
|
||||
//replace deleted color with lightest color
|
||||
replaceAllOfColor(color.jscolor.toString(),lightestColor[1].jscolor.toString());
|
||||
|
||||
|
||||
//if the color you are deleting is the currently selected color
|
||||
if (color.parentElement.classList.contains('selected')) {
|
||||
//console.log('%c'+'deleted color is currently selected', logStyle);
|
||||
|
||||
//set current color TO LIGHTEST COLOR
|
||||
lightestColor[1].parentElement.classList.add('selected');
|
||||
currentLayer.context.fillStyle = '#'+lightestColor[1].jscolor.toString();
|
||||
}
|
||||
|
||||
//delete the element
|
||||
colorsMenu.removeChild(color.parentElement);
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -379,7 +379,7 @@ function HistoryStateAddColor (colorValue) {
|
|||
|
||||
this.undo = function () {
|
||||
redoStates.push(this);
|
||||
deleteColor(this.colorValue);
|
||||
ColorModule.deleteColor(this.colorValue);
|
||||
};
|
||||
|
||||
this.redo = function () {
|
||||
|
@ -410,7 +410,7 @@ function HistoryStateDeleteColor (colorValue) {
|
|||
var currentCanvas = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
|
||||
currentLayer.context.putImageData(this.canvas, 0, 0);
|
||||
|
||||
deleteColor(this.colorValue);
|
||||
ColorModule.deleteColor(this.colorValue);
|
||||
|
||||
this.canvas = currentCanvas;
|
||||
undoStates.push(this);
|
||||
|
|
|
@ -553,7 +553,7 @@ if (!window.jscolor) { window.jscolor = (function () {
|
|||
//saveHistoryState({type: 'deletecolor', colorValue: jsc.picker.owner.toString(), canvas: canvas.context.getImageData(0, 0, canvasSize[0], canvasSize[1])});
|
||||
new HistoryStateDeleteColor(jsc.picker.owner.toString());
|
||||
|
||||
deleteColor(jsc.picker.owner.styleElement);
|
||||
ColorModule.deleteColor(jsc.picker.owner.styleElement);
|
||||
}
|
||||
else if (e.target.className == 'jscolor-picker-bottom') {
|
||||
//console.log('clicked color picker bottom')
|
||||
|
@ -1071,12 +1071,9 @@ if (!window.jscolor) { window.jscolor = (function () {
|
|||
this.hide = function () {
|
||||
///console.log(this.styleElement)
|
||||
if (isPickerOwner()) {
|
||||
|
||||
//console.log('color picker hidden')
|
||||
|
||||
//set the color to old color, in case the color is a duplicate that hasn't been resolved yet [lospec]
|
||||
var hexInput = document.getElementById('jscolor-hex-input');
|
||||
var oldColor = '#'+rgbToHex(hexInput.oldColor);
|
||||
var oldColor = '#'+Color.rgbToHex(hexInput.oldColor);
|
||||
this.fromString(oldColor);
|
||||
document.getElementById('duplicate-color-warning').style.visibility = 'hidden';
|
||||
|
||||
|
@ -1105,7 +1102,7 @@ if (!window.jscolor) { window.jscolor = (function () {
|
|||
this.exportColor();
|
||||
|
||||
//set old color for updating colors on canvas
|
||||
hexInput.oldColor = hexToRgb(hexInput.value);
|
||||
hexInput.oldColor = Color.hexToRgb(hexInput.value);
|
||||
|
||||
//set the color element to the clicked button
|
||||
hexInput.colorElement = this.styleElement;
|
||||
|
|
|
@ -117,12 +117,12 @@ function newPixel (width, height, editorMode, fileContent = null) {
|
|||
history.pushState(null, null, '/pixel-editor');
|
||||
|
||||
//generate default colors
|
||||
var fg = hslToRgb(Math.floor(Math.random()*255), 230,70);
|
||||
var bg = hslToRgb(Math.floor(Math.random()*255), 230,170);
|
||||
var fg = new Color("hsl", Math.floor(Math.random()*255), 230,70).rgb;
|
||||
var bg = new Color("hsl", Math.floor(Math.random()*255), 230,170).rgb;
|
||||
|
||||
//convert colors to hex
|
||||
var defaultForegroundColor = rgbToHex(fg.r,fg.g,fg.b);
|
||||
var defaultBackgroundColor = rgbToHex(bg.r,bg.g,bg.b);
|
||||
var defaultForegroundColor = Color.rgbToHex(fg);
|
||||
var defaultBackgroundColor = Color.rgbToHex(bg);
|
||||
|
||||
//add colors to palette
|
||||
ColorModule.addColor(defaultForegroundColor).classList.add('selected');
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
//replaces all of a single color on the canvas with a different color
|
||||
//input two rgb color objects {r:0,g:0,b:0}
|
||||
function replaceAllOfColor (oldColor, newColor) {
|
||||
|
||||
//convert strings to objects if nessesary
|
||||
if (typeof oldColor === 'string') oldColor = hexToRgb(oldColor);
|
||||
if (typeof newColor === 'string') newColor = hexToRgb(newColor);
|
||||
|
||||
//create temporary image from canvas to search through
|
||||
var tempImage = currentLayer.context.getImageData(0, 0, canvasSize[0], canvasSize[1]);
|
||||
|
||||
//loop through all pixels
|
||||
for (var i=0;i<tempImage.data.length;i+=4) {
|
||||
//check if pixel matches old color
|
||||
if(tempImage.data[i]==oldColor.r && tempImage.data[i+1]==oldColor.g && tempImage.data[i+2]==oldColor.b){
|
||||
//change to new color
|
||||
tempImage.data[i]=newColor.r;
|
||||
tempImage.data[i+1]=newColor.g;
|
||||
tempImage.data[i+2]=newColor.b;
|
||||
}
|
||||
}
|
||||
|
||||
//put temp image back onto canvas
|
||||
currentLayer.context.putImageData(tempImage,0,0);
|
||||
}
|
|
@ -3,15 +3,11 @@
|
|||
//=include util/onChildren.js
|
||||
//=include util/onClick.js
|
||||
//=include util/onClickChildren.js
|
||||
//=include util/hexToRgb.js
|
||||
//=include util/rgbToHex.js
|
||||
//=include util/rgbToHsl.js
|
||||
//=include util/hslToRgb.js
|
||||
//=include lib/cookies.js
|
||||
//=include _pixelEditorUtility.js
|
||||
//=include lib/sortable.js
|
||||
//=include _algorithms.js
|
||||
//=include Util.js
|
||||
//=include Color.js
|
||||
|
||||
/**init**/
|
||||
//=include _consts.js
|
||||
|
@ -37,8 +33,6 @@
|
|||
//=include _fill.js
|
||||
//=include _line.js
|
||||
//=include _history.js
|
||||
//=include _deleteColor.js
|
||||
//=include _replaceAllOfColor.js
|
||||
//=include _checkerboard.js
|
||||
//=include _pixelGrid.js
|
||||
//=include _layer.js
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
//GET: ajax(String url, Function success [,timeout])
|
||||
//POST: ajax(String url, Object postData, Function success [,timeout])
|
||||
Util.ajax = function (url, arg2, arg3, arg4) {
|
||||
if (typeof arg2 == 'function') {
|
||||
var success = arg2;
|
||||
var timeout = arg3 || 10000;
|
||||
}
|
||||
else {
|
||||
var postData = arg2;
|
||||
var success = arg3;
|
||||
var timeout = arg4 || 10000;
|
||||
}
|
||||
|
||||
var start = new Date();
|
||||
console.log('AJAX - STARTING REQUEST', url, '(' + timeout + ')');
|
||||
|
||||
//start new request
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var result;
|
||||
|
||||
//try to parse as json
|
||||
try {
|
||||
result = JSON.parse(this.response);
|
||||
console.log('AJAX - COMPLETE ('+(new Date()-start)+'ms) - json:', result);
|
||||
}
|
||||
catch (e) {
|
||||
result = this.response;
|
||||
console.log('AJAX - COMPLETE ('+(new Date()-start)+'ms) - string:', this.response, e);
|
||||
}
|
||||
|
||||
//return result
|
||||
success(result);
|
||||
|
||||
xhr = null;
|
||||
}
|
||||
else if (this.readyState == 4) {
|
||||
console.log('ajax failed', this.readyState, this.status);
|
||||
success({ error: 'failure' });
|
||||
}
|
||||
};
|
||||
|
||||
xhr.ontimeout = function(e) {
|
||||
console.log('ajax request timed out')
|
||||
success({ error: 'timeout' });
|
||||
};
|
||||
|
||||
if (postData) {
|
||||
//post request
|
||||
console.log('post data: ', postData instanceof FormData, postData);
|
||||
|
||||
//the the input isn't already formdata, convert it to form data
|
||||
if (!(postData instanceof FormData)) {
|
||||
console.log('converting to form data');
|
||||
|
||||
var formData = new FormData();
|
||||
|
||||
for (var key in postData) {
|
||||
formData.append(key, postData[key]);
|
||||
}
|
||||
|
||||
postData = formData;
|
||||
}
|
||||
|
||||
//send to server
|
||||
xhr.open("POST", url, true);
|
||||
xhr.timeout = timeout;
|
||||
xhr.send(postData);
|
||||
}
|
||||
else {
|
||||
//get request
|
||||
xhr.open("GET", url, true);
|
||||
xhr.timeout = timeout;
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
return xhr;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
//put in a hex color code (f464b2 or #f464b2) string
|
||||
//and get an rgb color object {r:0,g:0,b:0}
|
||||
//divisor is an optional argument, which makes it so you can get values other than 0-255
|
||||
|
||||
function hexToRgb(hex, divisor) {
|
||||
//if divisor isn't set, set it to one (so it has no effect)
|
||||
divisor = divisor || 1;
|
||||
|
||||
//split given hex code into array of 3 values
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex.trim());
|
||||
|
||||
//console.log('hex: '+hex)
|
||||
//console.log([parseInt(result[1], 16)/divisor, parseInt(result[2], 16)/divisor, parseInt(result[3], 16)/divisor])
|
||||
//console.log(result)
|
||||
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16)/divisor,
|
||||
g: parseInt(result[2], 16)/divisor,
|
||||
b: parseInt(result[3], 16)/divisor
|
||||
} : null;
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
function hslToRgb(h, s, l){
|
||||
h /= 255;
|
||||
s /= 255;
|
||||
l /= 255;
|
||||
|
||||
var r, g, b;
|
||||
|
||||
if(s == 0){
|
||||
r = g = b = l; // achromatic
|
||||
}else{
|
||||
var hue2rgb = function hue2rgb(p, q, t){
|
||||
if(t < 0) t += 1;
|
||||
if(t > 1) t -= 1;
|
||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||
if(t < 1/2) return q;
|
||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return {
|
||||
r:Math.round(r * 255),
|
||||
g:Math.round(g * 255),
|
||||
b:Math.round(b * 255)
|
||||
};
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
//convert rgb values to a hex string for html
|
||||
function rgbToHex (argument0,g,b) {
|
||||
var r;
|
||||
|
||||
//if the first argument is an object
|
||||
if (typeof argument0 === 'object'){
|
||||
r = argument0.r;
|
||||
g = argument0.g;
|
||||
b = argument0.b;
|
||||
}
|
||||
else
|
||||
r = argument0;
|
||||
|
||||
//console.log('converting rgb('+r+','+g+','+b+') to hex');
|
||||
|
||||
//convert a decimal number to 2-digit hex
|
||||
function componentToHex (c) {
|
||||
var hex = c.toString(16);
|
||||
return hex.length == 1 ? "0" + hex : hex;
|
||||
}
|
||||
|
||||
return componentToHex(r) + componentToHex(g) + componentToHex(b);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//put in red green blue values and get out hue saturation luminosity values
|
||||
|
||||
function rgbToHsl(argument0, g, b){
|
||||
var r;
|
||||
|
||||
//if the first argument is an object
|
||||
if (typeof argument0 === 'object'){
|
||||
r = argument0.r;
|
||||
g = argument0.g;
|
||||
b = argument0.b;
|
||||
}
|
||||
else
|
||||
r = argument0;
|
||||
|
||||
|
||||
|
||||
r /= 255, g /= 255, b /= 255;
|
||||
|
||||
var max = Math.max(r, g, b), min = Math.min(r, g, b);
|
||||
var hue, saturation, luminosity = (max + min) / 2;
|
||||
|
||||
if(max == min){
|
||||
hue = saturation = 0; // achromatic
|
||||
}else{
|
||||
var d = max - min;
|
||||
saturation = luminosity > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
switch(max){
|
||||
case r: hue = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: hue = (b - r) / d + 2; break;
|
||||
case b: hue = (r - g) / d + 4; break;
|
||||
}
|
||||
hue /= 6;
|
||||
}
|
||||
|
||||
return {h:hue, s:saturation, l:luminosity};
|
||||
}
|
Loading…
Reference in New Issue