mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Added sortable palette (basic mode)
Started advanced palette block
This commit is contained in:
parent
47b99bb430
commit
5ab5ceb6b0
@ -14,6 +14,8 @@ Suggestions / Planned features:
|
|||||||
|
|
||||||
- Documentation
|
- Documentation
|
||||||
|
|
||||||
|
- Possibility to hide and resize menus (layers, palette)
|
||||||
|
- What's new window to show the latest updates
|
||||||
- Line tool
|
- Line tool
|
||||||
- Tiled mode
|
- Tiled mode
|
||||||
- Load palette from LPE file
|
- Load palette from LPE file
|
||||||
|
@ -125,7 +125,7 @@ body {
|
|||||||
z-index: 1120;
|
z-index: 1120;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
overflow-y:scroll;
|
overflow-y:scroll;
|
||||||
overflow-x:hidden; // TODO: make the scroll bar a bit fancier
|
overflow-x:hidden;
|
||||||
#add-layer-button {
|
#add-layer-button {
|
||||||
path {
|
path {
|
||||||
fill: $baseicon;
|
fill: $baseicon;
|
||||||
@ -178,7 +178,7 @@ body {
|
|||||||
|
|
||||||
.layers-menu-entry {
|
.layers-menu-entry {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-top: 2px;
|
margin-bottom: 2px;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
color: $basetext;
|
color: $basetext;
|
||||||
background-color: lighten($basecolor, 4%);
|
background-color: lighten($basecolor, 4%);
|
||||||
@ -775,6 +775,31 @@ svg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.update {
|
||||||
|
input {
|
||||||
|
background: $indent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: $indenttext;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 0;
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
input {
|
||||||
|
background: $indent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: $indenttext;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 0;
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
button.default {
|
button.default {
|
||||||
float: right;
|
float: right;
|
||||||
background: $basehover;
|
background: $basehover;
|
||||||
@ -789,17 +814,6 @@ svg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
|
||||||
background: $indent;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
color: $indenttext;
|
|
||||||
padding: 10px 20px;
|
|
||||||
margin: 0;
|
|
||||||
width: 60px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-button {
|
.dropdown-button {
|
||||||
background: $basehover url('/pixel-editor/dropdown-arrow.png') right center no-repeat;
|
background: $basehover url('/pixel-editor/dropdown-arrow.png') right center no-repeat;
|
||||||
border: none;
|
border: none;
|
||||||
@ -1038,9 +1052,9 @@ svg {
|
|||||||
input[type=number] {
|
input[type=number] {
|
||||||
position:relative;
|
position:relative;
|
||||||
margin-left:10px;
|
margin-left:10px;
|
||||||
height:15px;
|
height:15px !important;
|
||||||
width:40px;
|
width:40px !important;
|
||||||
padding:8px;
|
padding:8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=number]::-webkit-outer-spin-button,
|
input[type=number]::-webkit-outer-spin-button,
|
||||||
@ -1213,3 +1227,286 @@ svg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/***********************COLOUR PICKER*****************************/
|
||||||
|
#colour-picker {
|
||||||
|
background-color:$basecolor;
|
||||||
|
width:250px;
|
||||||
|
position:absolute;
|
||||||
|
display:inline-block;
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
background-color:$basetext;
|
||||||
|
color:$basecolor;
|
||||||
|
box-shadow:none;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
width: 100%;
|
||||||
|
margin: 2.2px 0;
|
||||||
|
background-color: transparent;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
background: #484d4d;
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 25.6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
margin-top: -2.2px;
|
||||||
|
width: 18px;
|
||||||
|
height: 30px;
|
||||||
|
background: $basetext;
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
background: #484d4d;
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 25.6px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
width: 18px;
|
||||||
|
height: 30px;
|
||||||
|
background: $basetextweak;
|
||||||
|
border: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TODO: Use one of the selectors from https://stackoverflow.com/a/20541859/7077589 and figure out
|
||||||
|
how to remove the vertical space around the range input in IE*/
|
||||||
|
@supports (-ms-ime-align:auto) {
|
||||||
|
/* Pre-Chromium Edge only styles, selector taken from hhttps://stackoverflow.com/a/32202953/7077589 */
|
||||||
|
input[type=range].slider {
|
||||||
|
margin: 0;
|
||||||
|
/*Edge starts the margin from the thumb, not the track as other browsers do*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-modes {
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
font-size:0;
|
||||||
|
height:40px;
|
||||||
|
float:left;
|
||||||
|
display:flex;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
background-color:$basetextweak;
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size:14px;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
margin:0 0 0 0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
height:100%;
|
||||||
|
width:37x;
|
||||||
|
background-color:$basehover;
|
||||||
|
color:$basetext;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color:$baseicon;
|
||||||
|
color:$basetext;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.cp-selected-mode {
|
||||||
|
background-color:$baseicon;
|
||||||
|
color:$basetext;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width:50px;
|
||||||
|
right:0;
|
||||||
|
position:absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
background-color:yellow;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
z-index:2;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#sliders-container {
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-slider-entry {
|
||||||
|
width:100%;
|
||||||
|
height:30px;
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
margin-top:2px;
|
||||||
|
position:relative;
|
||||||
|
|
||||||
|
label {
|
||||||
|
width: 20px;
|
||||||
|
font-size:15px;
|
||||||
|
font-style: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
text-align:center;
|
||||||
|
width: 30px;
|
||||||
|
overflow:visible;
|
||||||
|
margin-left:4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.colour-picker-slider {
|
||||||
|
width:90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-minipicker {
|
||||||
|
width:100%;
|
||||||
|
height:100px;
|
||||||
|
position:relative;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
z-index: inherit 2000;
|
||||||
|
|
||||||
|
input {
|
||||||
|
width:100%;
|
||||||
|
margin: none;
|
||||||
|
padding: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-colours-previews {
|
||||||
|
width:100%;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-colour-preview {
|
||||||
|
width:100%;
|
||||||
|
position:relative;
|
||||||
|
background-color:blue;
|
||||||
|
color:$basecolor;
|
||||||
|
float:left;
|
||||||
|
height:30px;
|
||||||
|
justify-content: center;
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size:12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-colour-picking-modes {
|
||||||
|
width:100%;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size:14px;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
margin:0 0 0 0;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
height:30px;
|
||||||
|
width:16.66666%;
|
||||||
|
float:left;
|
||||||
|
overflow:hidden;
|
||||||
|
background-color:$basehover;
|
||||||
|
color:$basetext;
|
||||||
|
cursor:pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color:$baseicon;
|
||||||
|
color:$basetext;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.cp-selected-mode {
|
||||||
|
background-color:$baseicon;
|
||||||
|
color:$basetext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-canvas-container {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-spectrum {
|
||||||
|
width:100%;
|
||||||
|
height:100px;
|
||||||
|
position:absolute;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-picker-icon{
|
||||||
|
width:16px;
|
||||||
|
height:16px;
|
||||||
|
border-radius:100%;
|
||||||
|
position:absolute;
|
||||||
|
background-color:white;
|
||||||
|
z-index:2;
|
||||||
|
border:2px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************PALETTE BLOCK****************/
|
||||||
|
div#palette-block {
|
||||||
|
z-index:1000;
|
||||||
|
position:relative;
|
||||||
|
resize: horizontal;
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
width:600px;
|
||||||
|
height:400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#palette-container {
|
||||||
|
display:inline-block;
|
||||||
|
background-color:black;
|
||||||
|
position:relative;
|
||||||
|
scrollbar-color: #332f35 #232125;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
/*
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
background: #232125;
|
||||||
|
width: 0.5em;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
margin-top: -0.125em;
|
||||||
|
width: 0.5em;
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #332f35;
|
||||||
|
border-radius: 0.25em;
|
||||||
|
border: solid 0.125em #232125; //same color as scrollbar back to fake padding
|
||||||
|
}
|
||||||
|
&::-webkit-scrollbar-corner {
|
||||||
|
background: #232125;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#palette-list {
|
||||||
|
list-style:none;
|
||||||
|
margin: 0 0 0 0;
|
||||||
|
padding: 0 0 0 0;
|
||||||
|
position:relative;
|
||||||
|
display:inline-block;
|
||||||
|
|
||||||
|
li {
|
||||||
|
float:left;
|
||||||
|
width:50px;
|
||||||
|
height:50px;
|
||||||
|
border:none;
|
||||||
|
|
||||||
|
min-width:20px;
|
||||||
|
min-height:20px;
|
||||||
|
max-width:75px;
|
||||||
|
max-height:75px;
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ function addColor (newColor) {
|
|||||||
button.style.backgroundColor = newColor;
|
button.style.backgroundColor = newColor;
|
||||||
button.addEventListener('mouseup', clickedColor);
|
button.addEventListener('mouseup', clickedColor);
|
||||||
listItem.appendChild(button);
|
listItem.appendChild(button);
|
||||||
|
listItem.classList.add("draggable-colour")
|
||||||
|
|
||||||
//insert new listItem element at the end of the colors menu (right before add button)
|
//insert new listItem element at the end of the colors menu (right before add button)
|
||||||
colorsMenu.insertBefore(listItem, colorsMenu.children[colorsMenu.children.length-1]);
|
colorsMenu.insertBefore(listItem, colorsMenu.children[colorsMenu.children.length-1]);
|
||||||
@ -37,11 +38,21 @@ function addColor (newColor) {
|
|||||||
//hide edit button
|
//hide edit button
|
||||||
button.parentElement.lastChild.classList.add('hidden');
|
button.parentElement.lastChild.classList.add('hidden');
|
||||||
|
|
||||||
//show jscolor picker
|
//show jscolor picker, if basic mode is enabled
|
||||||
|
if (pixelEditorMode == 'Basic')
|
||||||
button.parentElement.firstChild.jscolor.show();
|
button.parentElement.firstChild.jscolor.show();
|
||||||
|
else
|
||||||
|
showDialogue("palette-block", false);
|
||||||
});
|
});
|
||||||
|
|
||||||
//console.log(currentPalette);
|
//console.log(currentPalette);
|
||||||
|
|
||||||
return listItem;
|
return listItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new Sortable(document.getElementById("colors-menu"), {
|
||||||
|
animation:100,
|
||||||
|
filter: ".noshrink",
|
||||||
|
draggable: ".draggable-colour",
|
||||||
|
onEnd: makeIsDraggingFalse
|
||||||
|
});
|
185
js/_algorithms.js
Normal file
185
js/_algorithms.js
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
808
js/_colorPicker.js
Normal file
808
js/_colorPicker.js
Normal file
@ -0,0 +1,808 @@
|
|||||||
|
let sliders = document.getElementsByClassName("cp-slider-entry");
|
||||||
|
let colourPreview = document.getElementById("cp-colour-preview");
|
||||||
|
let colourValue = document.getElementById("cp-hex");
|
||||||
|
let currentPickerMode = "rgb";
|
||||||
|
let currentPickingMode = "mono";
|
||||||
|
let styleElement = document.createElement("style");
|
||||||
|
let miniPickerCanvas = document.getElementById("cp-spectrum");
|
||||||
|
let miniPickerSlider = document.getElementById("cp-minipicker-slider");
|
||||||
|
let activePickerIcon = document.getElementById("cp-active-icon");
|
||||||
|
let pickerIcons = [activePickerIcon];
|
||||||
|
let hexContainers = [document.getElementById("cp-colours-previews").children[0],null,null,null];
|
||||||
|
let startPickerIconPos = [[0,0],[0,0],[0,0],[0,0]];
|
||||||
|
let currPickerIconPos = [[0,0], [0,0],[0,0],[0,0]];
|
||||||
|
let styles = ["",""];
|
||||||
|
let draggingCursor = false;
|
||||||
|
|
||||||
|
cpInit();
|
||||||
|
|
||||||
|
function cpInit() {
|
||||||
|
// Appending the palette styles
|
||||||
|
document.getElementsByTagName("head")[0].appendChild(styleElement);
|
||||||
|
|
||||||
|
// Saving first icon position
|
||||||
|
startPickerIconPos[0] = [miniPickerCanvas.getBoundingClientRect().left, miniPickerCanvas.getBoundingClientRect().top];
|
||||||
|
// Set the correct size of the canvas
|
||||||
|
miniPickerCanvas.height = miniPickerCanvas.getBoundingClientRect().height;
|
||||||
|
miniPickerCanvas.width = miniPickerCanvas.getBoundingClientRect().width;
|
||||||
|
|
||||||
|
// Update picker position
|
||||||
|
updatePickerByHex(colourValue.value);
|
||||||
|
// Startup updating
|
||||||
|
updateAllSliders();
|
||||||
|
// Fill minislider
|
||||||
|
updateMiniSlider(colourValue.value);
|
||||||
|
// Fill minipicker
|
||||||
|
updatePickerByHex(colourValue.value);
|
||||||
|
|
||||||
|
updateMiniPickerSpectrum();
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexUpdated() {
|
||||||
|
updatePickerByHex(colourValue.value);
|
||||||
|
updateSlidersByHex(colourValue.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Applies the styles saved in the style array to the style element in the head of the document
|
||||||
|
function updateStyles() {
|
||||||
|
styleElement.innerHTML = styles[0] + styles[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates the background gradients of the sliders given their value
|
||||||
|
* Updates the hex colour and its preview
|
||||||
|
* Updates the minipicker according to the computed hex colour
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function updateSliderValue (sliderIndex, updateMini = true) {
|
||||||
|
let toUpdate;
|
||||||
|
let slider;
|
||||||
|
let input;
|
||||||
|
let hexColour;
|
||||||
|
let sliderValues;
|
||||||
|
|
||||||
|
toUpdate = sliders[sliderIndex - 1];
|
||||||
|
|
||||||
|
slider = toUpdate.getElementsByTagName("input")[0];
|
||||||
|
input = toUpdate.getElementsByTagName("input")[1];
|
||||||
|
|
||||||
|
// Update label value
|
||||||
|
input.value = slider.value;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
// Update preview colour div
|
||||||
|
colourPreview.style.backgroundColor = '#' + hexColour;
|
||||||
|
colourValue.value = '#' + hexColour;
|
||||||
|
|
||||||
|
// Update sliders background
|
||||||
|
// there's no other way than creating a custom css file, appending it to the head and
|
||||||
|
// specify the sliders' backgrounds here
|
||||||
|
|
||||||
|
styles[0] = '';
|
||||||
|
for (let i=0; i<sliders.length; i++) {
|
||||||
|
styles[0] += getSliderCSS(i + 1, sliderValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStyles();
|
||||||
|
|
||||||
|
if (updateMini) {
|
||||||
|
updatePickerByHex(colourValue.value);
|
||||||
|
updateMiniPickerSpectrum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculates the css gradient for a slider
|
||||||
|
function getSliderCSS(index, sliderValues) {
|
||||||
|
let ret = 'input[type=range]#';
|
||||||
|
let sliderId;
|
||||||
|
let gradientMin;
|
||||||
|
let gradientMax;
|
||||||
|
let hueGradient;
|
||||||
|
let rgbColour;
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 1:
|
||||||
|
sliderId = 'first-slider';
|
||||||
|
switch (currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
gradientMin = 'rgba(0,' + sliderValues[1] + ',' + sliderValues[2] + ',1)';
|
||||||
|
gradientMax = 'rgba(255,' + sliderValues[1] + ',' + sliderValues[2] + ',1)';
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
hueGradient = getHueGradientHSV(sliderValues);
|
||||||
|
break;
|
||||||
|
case 'hsl':
|
||||||
|
// Hue gradient
|
||||||
|
hueGradient = getHueGradientHSL(sliderValues);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sliderId = 'second-slider';
|
||||||
|
switch (currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
gradientMin = 'rgba(' + sliderValues[0] + ',0,' + sliderValues[2] + ',1)';
|
||||||
|
gradientMax = 'rgba(' + sliderValues[0] + ',255,' + sliderValues[2] + ',1)';
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
rgbColour = hsvToRgb(sliderValues[0], 0, sliderValues[2]);
|
||||||
|
gradientMin = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
|
||||||
|
rgbColour = hsvToRgb(sliderValues[0], 100, sliderValues[2]);
|
||||||
|
gradientMax = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
break;
|
||||||
|
case 'hsl':
|
||||||
|
rgbColour = cpHslToRgb(sliderValues[0], 0, sliderValues[2]);
|
||||||
|
gradientMin = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
|
||||||
|
rgbColour = cpHslToRgb(sliderValues[0], 100, sliderValues[2]);
|
||||||
|
gradientMax = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sliderId = 'third-slider';
|
||||||
|
switch (currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
gradientMin = 'rgba(' + sliderValues[0] + ',' + sliderValues[1] + ',0,1)';
|
||||||
|
gradientMax = 'rgba(' + sliderValues[0] + ',' + sliderValues[1] + ',255,1)';
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
rgbColour = hsvToRgb(sliderValues[0], sliderValues[1], 0);
|
||||||
|
gradientMin = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
|
||||||
|
rgbColour = hsvToRgb(sliderValues[0], sliderValues[1], 100);
|
||||||
|
gradientMax = 'rgba(' + rgbColour[0] + ',' + rgbColour[1] + ',' + rgbColour[2] + ',1)';
|
||||||
|
break;
|
||||||
|
case 'hsl':
|
||||||
|
gradientMin = 'rgba(0,0,0,1)';
|
||||||
|
gradientMax = 'rgba(255,255,255,1)';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += sliderId;
|
||||||
|
ret += '::-webkit-slider-runnable-track {';
|
||||||
|
|
||||||
|
switch (currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
ret += 'background: linear-gradient(90deg, rgba(2,0,36,1) 0%, ' +
|
||||||
|
gradientMin + ' 0%, ' + gradientMax + '100%)';
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
case 'hsl':
|
||||||
|
ret += 'background: ';
|
||||||
|
if (index == 1) {
|
||||||
|
ret += hueGradient;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret += 'linear-gradient(90deg, rgba(2,0,36,1) 0%, ' + gradientMin + ' 0%, ';
|
||||||
|
// For hsl I also have to add a middle point
|
||||||
|
if (currentPickerMode == 'hsl' && index == 3) {
|
||||||
|
let rgb = cpHslToRgb(sliderValues[0], sliderValues[1], 50);
|
||||||
|
ret += 'rgba(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ',1) 50%,';
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += gradientMax + '100%);';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += '}'
|
||||||
|
|
||||||
|
ret += ret.replace('::-webkit-slider-runnable-track', '::-moz-range-track');
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the hue gradient used for hsl
|
||||||
|
function getHueGradientHSL(sliderValues) {
|
||||||
|
return 'linear-gradient(90deg, rgba(2,0,36,1) 0%, \
|
||||||
|
hsl(0,' + sliderValues[1] + '%,' + sliderValues[2]+ '%) 0%, \
|
||||||
|
hsl(60,' + sliderValues[1] + '%,' + sliderValues[2]+ '%) 16.6666%, \
|
||||||
|
hsl(120,' + sliderValues[1] + '%,' + sliderValues[2]+ '%) 33.3333333333%, \
|
||||||
|
hsl(180,'+ sliderValues[1] + '%,' + sliderValues[2]+ '%) 50%, \
|
||||||
|
hsl(240,' + sliderValues[1] + '%,' + sliderValues[2]+ '%) 66.66666%, \
|
||||||
|
hsl(300,'+ sliderValues[1] + '%,' + sliderValues[2]+ '%) 83.333333%, \
|
||||||
|
hsl(360,'+ sliderValues[1] + '%,' + sliderValues[2]+ '%) 100%);';
|
||||||
|
}
|
||||||
|
// Computes the hue gradient used for hsv
|
||||||
|
function getHueGradientHSV(sliderValues) {
|
||||||
|
let col = hsvToRgb(0, sliderValues[1], sliderValues[2]);
|
||||||
|
let ret = 'linear-gradient(90deg, rgba(2,0,36,1) 0%, ';
|
||||||
|
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 0%,'
|
||||||
|
|
||||||
|
col = hsvToRgb(60, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 16.6666%,';
|
||||||
|
|
||||||
|
col = hsvToRgb(120, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 33.3333333333%,';
|
||||||
|
|
||||||
|
col = hsvToRgb(180, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 50%,';
|
||||||
|
|
||||||
|
col = hsvToRgb(240, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 66.66666%,';
|
||||||
|
|
||||||
|
col = hsvToRgb(300, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 83.333333%,';
|
||||||
|
|
||||||
|
col = hsvToRgb(360, sliderValues[1], sliderValues[2]);
|
||||||
|
ret += 'rgba(' + col[0] + ',' + col[1] + ',' + col[2] + ',1) 100%);';
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fired when the values in the labels are changed
|
||||||
|
function inputChanged(target, index) {
|
||||||
|
let sliderIndex = index - 1;
|
||||||
|
|
||||||
|
sliders[sliderIndex].getElementsByTagName("input")[0].value = target.value;
|
||||||
|
updateSliderValue(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the colour model used to pick colours
|
||||||
|
function changePickerMode(target, newMode) {
|
||||||
|
let maxRange;
|
||||||
|
let colArray;
|
||||||
|
let rgbTmp;
|
||||||
|
let hexColour = colourValue.value.replace('#', '');
|
||||||
|
|
||||||
|
currentPickerMode = newMode;
|
||||||
|
document.getElementsByClassName("cp-selected-mode")[0].classList.remove("cp-selected-mode");
|
||||||
|
target.classList.add("cp-selected-mode");
|
||||||
|
|
||||||
|
switch (newMode)
|
||||||
|
{
|
||||||
|
case 'rgb':
|
||||||
|
maxRange = [255,255,255];
|
||||||
|
sliders[0].getElementsByTagName("label")[0].innerHTML = 'R';
|
||||||
|
sliders[1].getElementsByTagName("label")[0].innerHTML = 'G';
|
||||||
|
sliders[2].getElementsByTagName("label")[0].innerHTML = 'B';
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
maxRange = [360, 100, 100];
|
||||||
|
sliders[0].getElementsByTagName("label")[0].innerHTML = 'H';
|
||||||
|
sliders[1].getElementsByTagName("label")[0].innerHTML = 'S';
|
||||||
|
sliders[2].getElementsByTagName("label")[0].innerHTML = 'V';
|
||||||
|
break;
|
||||||
|
case 'hsl':
|
||||||
|
maxRange = [360, 100, 100];
|
||||||
|
sliders[0].getElementsByTagName("label")[0].innerHTML = 'H';
|
||||||
|
sliders[1].getElementsByTagName("label")[0].innerHTML = 'S';
|
||||||
|
sliders[2].getElementsByTagName("label")[0].innerHTML = 'L';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("wtf select a decent picker mode");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i=0; i<sliders.length; i++) {
|
||||||
|
let slider = sliders[i].getElementsByTagName("input")[0];
|
||||||
|
|
||||||
|
slider.setAttribute("max", maxRange[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Putting the current colour in the new slider
|
||||||
|
switch(currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
colArray = hexToRgb(hexColour);
|
||||||
|
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 = [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 = [colArray.h, colArray.s, colArray.l];
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i=0; i<3; i++) {
|
||||||
|
sliders[i].getElementsByTagName("input")[0].value = colArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAllSliders();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns an array containing the values of the sliders
|
||||||
|
function getSlidersValues() {
|
||||||
|
return [parseInt(sliders[0].getElementsByTagName("input")[0].value),
|
||||||
|
parseInt(sliders[1].getElementsByTagName("input")[0].value),
|
||||||
|
parseInt(sliders[2].getElementsByTagName("input")[0].value)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates every slider
|
||||||
|
function updateAllSliders(updateMini=true) {
|
||||||
|
for (let i=1; i<=3; i++) {
|
||||||
|
updateSliderValue(i, updateMini);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/******************SECTION: MINIPICKER******************/
|
||||||
|
|
||||||
|
// Moves the picker icon according to the mouse position on the canvas
|
||||||
|
function movePickerIcon(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (event.which == 1 || draggingCursor) {
|
||||||
|
let cursorPos = getCursorPosMinipicker(event);
|
||||||
|
let canvasRect = miniPickerCanvas.getBoundingClientRect();
|
||||||
|
|
||||||
|
let left = (cursorPos[0] - startPickerIconPos[0][0] - 8);
|
||||||
|
let top = (cursorPos[1] - startPickerIconPos[0][1] - 8);
|
||||||
|
|
||||||
|
console.log(left + "," + top);
|
||||||
|
|
||||||
|
if (left > -8 && top > -8 && left < canvasRect.width-8 && top < canvasRect.height-8){
|
||||||
|
activePickerIcon.style["left"] = "" + left + "px";
|
||||||
|
activePickerIcon.style["top"]= "" + top + "px";
|
||||||
|
|
||||||
|
currPickerIconPos[0] = [left, top];
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMiniPickerColour();
|
||||||
|
updateOtherIcons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the main sliders given a hex value computed with the minipicker
|
||||||
|
function updateSlidersByHex(hex, updateMini = true) {
|
||||||
|
let colour;
|
||||||
|
let mySliders = [sliders[0].getElementsByTagName("input")[0],
|
||||||
|
sliders[1].getElementsByTagName("input")[0],
|
||||||
|
sliders[2].getElementsByTagName("input")[0]];
|
||||||
|
|
||||||
|
switch (currentPickerMode) {
|
||||||
|
case 'rgb':
|
||||||
|
colour = hexToRgb(hex);
|
||||||
|
|
||||||
|
mySliders[0].value = colour.r;
|
||||||
|
mySliders[1].value = colour.g;
|
||||||
|
mySliders[2].value = colour.b;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'hsv':
|
||||||
|
colour = rgbToHsv(hexToRgb(hex));
|
||||||
|
|
||||||
|
mySliders[0].value = colour.h * 360;
|
||||||
|
mySliders[1].value = colour.s * 100;
|
||||||
|
mySliders[2].value = colour.v * 100;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'hsl':
|
||||||
|
colour = rgbToHsl(hexToRgb(hex));
|
||||||
|
|
||||||
|
mySliders[0].value = colour.h * 360;
|
||||||
|
mySliders[1].value = colour.s * 100;
|
||||||
|
mySliders[2].value = colour.l * 100;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAllSliders(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the position of the picker cursor relative to the canvas
|
||||||
|
function getCursorPosMinipicker(e) {
|
||||||
|
var x;
|
||||||
|
var y;
|
||||||
|
|
||||||
|
if (e.pageX != undefined && e.pageY != undefined) {
|
||||||
|
x = e.pageX;
|
||||||
|
y = e.pageY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
|
||||||
|
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
x -= miniPickerCanvas.offsetLeft;
|
||||||
|
y -= miniPickerCanvas.offsetTop;
|
||||||
|
|
||||||
|
return [Math.round(x), Math.round(y)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the minipicker given a hex computed by the main sliders
|
||||||
|
// Moves the cursor
|
||||||
|
function updatePickerByHex(hex) {
|
||||||
|
let hsv = rgbToHsv(hexToRgb(hex));
|
||||||
|
let xPos = miniPickerCanvas.width * hsv.h - 8;
|
||||||
|
let yPos = miniPickerCanvas.height * hsv.s + 8;
|
||||||
|
|
||||||
|
miniPickerSlider.value = hsv.v * 100;
|
||||||
|
|
||||||
|
currPickerIconPos[0][0] = xPos;
|
||||||
|
currPickerIconPos[0][1] = miniPickerCanvas.height - yPos;
|
||||||
|
|
||||||
|
if (currPickerIconPos[0][1] >= 92)
|
||||||
|
{
|
||||||
|
currPickerIconPos[0][1] = 91.999;
|
||||||
|
}
|
||||||
|
|
||||||
|
activePickerIcon.style.left = '' + xPos + 'px';
|
||||||
|
activePickerIcon.style.top = '' + (miniPickerCanvas.height - yPos) + 'px';
|
||||||
|
activePickerIcon.style.backgroundColor = '#' + getMiniPickerColour();
|
||||||
|
|
||||||
|
updateOtherIcons();
|
||||||
|
updateMiniSlider(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 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]));
|
||||||
|
|
||||||
|
colourValue.value = newHex;
|
||||||
|
|
||||||
|
updateMiniPickerSpectrum();
|
||||||
|
updateMiniPickerColour();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the hex colour after having changed the minislider (MERGE)
|
||||||
|
function updateMiniPickerColour() {
|
||||||
|
let hex = getMiniPickerColour();
|
||||||
|
|
||||||
|
activePickerIcon.style.backgroundColor = '#' + hex;
|
||||||
|
|
||||||
|
// Update hex and sliders based on hex
|
||||||
|
colourValue.value = '#' + hex;
|
||||||
|
colourPreview.style.backgroundColor = '#' + hex;
|
||||||
|
|
||||||
|
updateSlidersByHex(hex);
|
||||||
|
updateMiniSlider(hex);
|
||||||
|
updateOtherIcons();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the current colour of the minipicker
|
||||||
|
function getMiniPickerColour() {
|
||||||
|
let hex;
|
||||||
|
let pickedColour;
|
||||||
|
console.log(currPickerIconPos[0]);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the background gradient of the slider in the minipicker
|
||||||
|
function updateMiniSlider(hex) {
|
||||||
|
let rgb = 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%, " +
|
||||||
|
"rgba(" + rgb.r + "," + rgb.g + "," + rgb.b + ",1) 100%);}";
|
||||||
|
|
||||||
|
updateStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the gradient of the spectrum canvas in the minipicker
|
||||||
|
function updateMiniPickerSpectrum() {
|
||||||
|
let ctx = miniPickerCanvas.getContext('2d');
|
||||||
|
let hsv = rgbToHsv(hexToRgb(colourValue.value));
|
||||||
|
let tmp;
|
||||||
|
let white = {h:hsv.h * 360, s:0, v: parseInt(miniPickerSlider.value)};
|
||||||
|
|
||||||
|
white = hsvToRgb(white.h, white.s, white.v);
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, miniPickerCanvas.width, miniPickerCanvas.height);
|
||||||
|
|
||||||
|
// Drawing hues
|
||||||
|
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])));
|
||||||
|
}
|
||||||
|
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)');
|
||||||
|
|
||||||
|
ctx.fillStyle = vGrad;
|
||||||
|
ctx.fillRect(0, 0, miniPickerCanvas.width, miniPickerCanvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleDraggingCursor() {
|
||||||
|
draggingCursor = !draggingCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changePickingMode(event, newMode) {
|
||||||
|
let nIcons = pickerIcons.length;
|
||||||
|
let canvasContainer = document.getElementById("cp-canvas-container");
|
||||||
|
// Number of hex containers to add
|
||||||
|
let nHexContainers;
|
||||||
|
|
||||||
|
// Remove selected class from previous mode
|
||||||
|
document.getElementById("cp-colour-picking-modes").getElementsByClassName("cp-selected-mode")[0].classList.remove("cp-selected-mode");
|
||||||
|
// Updating mode
|
||||||
|
currentPickingMode = newMode;
|
||||||
|
// Adding selected class to new mode
|
||||||
|
event.target.classList.add("cp-selected-mode");
|
||||||
|
|
||||||
|
for (let i=1; i<nIcons; i++) {
|
||||||
|
// Deleting extra icons
|
||||||
|
pickerIcons.pop();
|
||||||
|
canvasContainer.removeChild(canvasContainer.children[2]);
|
||||||
|
|
||||||
|
// Deleting extra hex containers
|
||||||
|
console.log("Deleting :O");
|
||||||
|
hexContainers[0].parentElement.removeChild(hexContainers[0].parentElement.children[1]);
|
||||||
|
hexContainers[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resetting first hex container size
|
||||||
|
hexContainers[0].style.width = '100%';
|
||||||
|
|
||||||
|
switch (currentPickingMode)
|
||||||
|
{
|
||||||
|
case 'analog':
|
||||||
|
createIcon();
|
||||||
|
createIcon();
|
||||||
|
|
||||||
|
nHexContainers = 2;
|
||||||
|
break;
|
||||||
|
case 'cmpt':
|
||||||
|
// Easiest one, add 180 to the H value and move the icon
|
||||||
|
createIcon();
|
||||||
|
nHexContainers = 1;
|
||||||
|
break;
|
||||||
|
case 'tri':
|
||||||
|
createIcon();
|
||||||
|
createIcon();
|
||||||
|
nHexContainers = 2;
|
||||||
|
break
|
||||||
|
case 'scmpt':
|
||||||
|
createIcon();
|
||||||
|
createIcon();
|
||||||
|
nHexContainers = 2;
|
||||||
|
break;
|
||||||
|
case 'tetra':
|
||||||
|
for (let i=0; i<3; i++) {
|
||||||
|
createIcon();
|
||||||
|
}
|
||||||
|
nHexContainers = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("How did you select the " + currentPickingMode + ", hackerman?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editing the size of the first container
|
||||||
|
hexContainers[0].style.width = '' + 100 / (nHexContainers + 1) + '%';
|
||||||
|
// Adding hex preview containers
|
||||||
|
for (let i=0; i<nHexContainers; i++) {
|
||||||
|
let newContainer = document.createElement("div");
|
||||||
|
newContainer.classList.add("cp-colour-preview");
|
||||||
|
newContainer.style.width = "" + (100 / (nHexContainers + 1)) + "%";
|
||||||
|
|
||||||
|
hexContainers[0].parentElement.appendChild(newContainer);
|
||||||
|
hexContainers[i + 1] = newContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createIcon() {
|
||||||
|
let newIcon = document.createElement("div");
|
||||||
|
newIcon.classList.add("cp-picker-icon");
|
||||||
|
pickerIcons.push(newIcon);
|
||||||
|
|
||||||
|
canvasContainer.appendChild(newIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOtherIcons();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOtherIcons() {
|
||||||
|
let currentColorHex = colourValue.value;
|
||||||
|
let currentColourHsv = rgbToHsv(hexToRgb(currentColorHex));
|
||||||
|
let newColourHsv = {h:currentColourHsv.h, s:currentColourHsv.s, v:currentColourHsv.v};
|
||||||
|
let newColourHexes = ['', '', ''];
|
||||||
|
let tmpRgb;
|
||||||
|
|
||||||
|
// Salvo tutti i
|
||||||
|
|
||||||
|
switch (currentPickingMode)
|
||||||
|
{
|
||||||
|
case 'mono':
|
||||||
|
break;
|
||||||
|
case 'analog':
|
||||||
|
// First colour
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 40) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
|
||||||
|
// Second colour
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 - 40) % 360) / 360);
|
||||||
|
if (newColourHsv.h < 0) {
|
||||||
|
newColourHsv.h += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]));
|
||||||
|
break;
|
||||||
|
case 'cmpt':
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 180) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
break;
|
||||||
|
case 'tri':
|
||||||
|
for (let i=1; i< 3; i++) {
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 120*i) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
case 'scmpt':
|
||||||
|
// First colour
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 210) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
|
||||||
|
// Second colour
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 150) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
break;
|
||||||
|
case 'tetra':
|
||||||
|
for (let i=1; i< 4; i++) {
|
||||||
|
newColourHsv.h = (((currentColourHsv.h*360 + 90*i) % 360) / 360);
|
||||||
|
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("How did you select the " + currentPickingMode + ", hackerman?");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hexContainers[0].style.color = getHexPreviewColour(colourValue.value);
|
||||||
|
|
||||||
|
for (let i=1; i<pickerIcons.length; i++) {
|
||||||
|
pickerIcons[i].style.left = '' + currPickerIconPos[i][0] + 'px';
|
||||||
|
pickerIcons[i].style.top = '' + currPickerIconPos[i][1] + 'px';
|
||||||
|
|
||||||
|
pickerIcons[i].style.backgroundColor = '#' + newColourHexes[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPickingMode != "analog") {
|
||||||
|
hexContainers[0].style.backgroundColor = colourValue.value;
|
||||||
|
hexContainers[0].innerHTML = colourValue.value;
|
||||||
|
|
||||||
|
for (let i=0; i<pickerIcons.length - 1; i++) {
|
||||||
|
hexContainers[i + 1].style.backgroundColor = '#' + newColourHexes[i];
|
||||||
|
hexContainers[i + 1].innerHTML = '#' + newColourHexes[i];
|
||||||
|
hexContainers[i + 1].style.color = getHexPreviewColour(newColourHexes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If I'm using analogous mode, I place the current colour in the middle
|
||||||
|
else {
|
||||||
|
console.log("si si si sonooo sono qui");
|
||||||
|
hexContainers[1].style.backgroundColor = colourValue.value;
|
||||||
|
hexContainers[1].innerHTML = colourValue.value;
|
||||||
|
|
||||||
|
hexContainers[2].style.backgroundColor = '#' + newColourHexes[0];
|
||||||
|
hexContainers[2].innerHTML = '#' + newColourHexes[0];
|
||||||
|
|
||||||
|
hexContainers[0].style.backgroundColor = '#' + newColourHexes[1];
|
||||||
|
hexContainers[0].innerHTML = '#' + newColourHexes[1];
|
||||||
|
|
||||||
|
for (let i=1; i<3; i++) {
|
||||||
|
hexContainers[i].style.color = getHexPreviewColour(newColourHexes[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedColours() {
|
||||||
|
let ret = [];
|
||||||
|
|
||||||
|
for (let i=0; i<hexContainers.length; i++) {
|
||||||
|
if (hexContainers[i] != null) {
|
||||||
|
ret.push(hexContainers[i].innerHTML);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHexPreviewColour(hex) {
|
||||||
|
|
||||||
|
//if brightness is over threshold, make the text dark
|
||||||
|
if (colorBrightness(hex) > 110) {
|
||||||
|
return '#332f35'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '#c2bbc7';
|
||||||
|
}
|
||||||
|
|
||||||
|
//take in a color and return its brightness
|
||||||
|
function colorBrightness (color) {
|
||||||
|
var r = parseInt(color.slice(1, 3), 16);
|
||||||
|
var g = parseInt(color.slice(3, 5), 16);
|
||||||
|
var b = parseInt(color.slice(5, 7), 16);
|
||||||
|
return Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000);
|
||||||
|
}
|
||||||
|
}
|
@ -87,5 +87,5 @@ function createPaletteFromLayers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//create palette form colors array
|
//create palette form colors array
|
||||||
createColorPalette(colorPaletteArray, false);
|
//createColorPalette(colorPaletteArray, false);
|
||||||
}
|
}
|
@ -18,12 +18,11 @@ function switchMode(currentMode, mustConfirm = true) {
|
|||||||
// Show the layer menus
|
// Show the layer menus
|
||||||
layerList.style.display = "inline-block";
|
layerList.style.display = "inline-block";
|
||||||
document.getElementById('layer-button').style.display = 'inline-block';
|
document.getElementById('layer-button').style.display = 'inline-block';
|
||||||
// Move the palette menu
|
// Hide the palette menu
|
||||||
document.getElementById('colors-menu').style.right = '200px';
|
document.getElementById('colors-menu').style.right = '200px'
|
||||||
|
|
||||||
pixelEditorMode = 'Advanced';
|
pixelEditorMode = 'Advanced';
|
||||||
}
|
}
|
||||||
|
|
||||||
//switch to basic mode
|
//switch to basic mode
|
||||||
else {
|
else {
|
||||||
//if there is a current layer (a document is active)
|
//if there is a current layer (a document is active)
|
||||||
@ -47,6 +46,8 @@ function switchMode(currentMode, mustConfirm = true) {
|
|||||||
// Hide the layer menus
|
// Hide the layer menus
|
||||||
layerList.style.display = 'none';
|
layerList.style.display = 'none';
|
||||||
document.getElementById('layer-button').style.display = 'none';
|
document.getElementById('layer-button').style.display = 'none';
|
||||||
|
// Show the palette menu
|
||||||
|
document.getElementById('colors-menu').style.display = 'flex';
|
||||||
// Move the palette menu
|
// Move the palette menu
|
||||||
document.getElementById('colors-menu').style.right = '0px';
|
document.getElementById('colors-menu').style.right = '0px';
|
||||||
|
|
||||||
|
@ -261,3 +261,10 @@ 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;
|
||||||
|
}
|
@ -13,6 +13,7 @@
|
|||||||
//=include libraries/cookies.js
|
//=include libraries/cookies.js
|
||||||
//=include _pixelEditorUtility.js
|
//=include _pixelEditorUtility.js
|
||||||
//=include sortable.js
|
//=include sortable.js
|
||||||
|
//=include _algorithms.js
|
||||||
|
|
||||||
/**init**/
|
/**init**/
|
||||||
//=include _consts.js
|
//=include _consts.js
|
||||||
@ -48,6 +49,7 @@
|
|||||||
//=include _copyPaste.js
|
//=include _copyPaste.js
|
||||||
//=include _resizeCanvas.js
|
//=include _resizeCanvas.js
|
||||||
//=include _resizeSprite.js
|
//=include _resizeSprite.js
|
||||||
|
//=include _colorPicker.js
|
||||||
|
|
||||||
/**load file**/
|
/**load file**/
|
||||||
//=include _loadImage.js
|
//=include _loadImage.js
|
||||||
|
@ -139,14 +139,7 @@
|
|||||||
<li><button title = "Rectangular Selection Tool (M)" id = "rectselect-button">{{svg "rectselect.svg" width = "32" height = "32"}}</button><li>
|
<li><button title = "Rectangular Selection Tool (M)" id = "rectselect-button">{{svg "rectselect.svg" width = "32" height = "32"}}</button><li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<!-- PALETTE -->
|
|
||||||
<ul id="colors-menu">
|
<ul id="colors-menu">
|
||||||
|
|
||||||
{{!
|
|
||||||
<li class="noshrink"><button id="current-color" class="jscolor {valueElement: 'current-color-value', styleElement: 'current-color-preview', onFineChange:'setColor(this)', width:151, position: 'left', padding:0,
|
|
||||||
borderWidth:14, borderColor: '#332f35',backgroundColor: '#332f35', insetColor:'transparent'}"><div id="current-color-preview"></div></button><input id="current-color-value" class="color-value" value="#000000" autocomplete="off" /></li>
|
|
||||||
}}
|
|
||||||
|
|
||||||
<li class="noshrink"><button title="Add Current Color To Palette" id="add-color-button">{{svg "./plus.svg" width="30" height="30"}}</button></li>
|
<li class="noshrink"><button title="Add Current Color To Palette" id="add-color-button">{{svg "./plus.svg" width="30" height="30"}}</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -232,9 +225,9 @@
|
|||||||
{{svg "adjust.svg" width="20" height="20" }}
|
{{svg "adjust.svg" width="20" height="20" }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="pop-up-container" id = "new-pixel-container">
|
<div id="pop-up-container">
|
||||||
<!-- NEW PIXEL -->
|
<!-- NEW PIXEL -->
|
||||||
<div id="new-pixel">
|
<div id="new-pixel" class="update">
|
||||||
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
||||||
<h1>New Pixel</h1>
|
<h1>New Pixel</h1>
|
||||||
|
|
||||||
@ -263,7 +256,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--SPRITE RESIZE-->
|
<!--SPRITE RESIZE-->
|
||||||
<div id = "resize-sprite">
|
<div class="update" id = "resize-sprite">
|
||||||
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
||||||
<h1>Scale sprite</h1>
|
<h1>Scale sprite</h1>
|
||||||
<!-- SIZE-->
|
<!-- SIZE-->
|
||||||
@ -313,7 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--CANVAS RESIZE-->
|
<!--CANVAS RESIZE-->
|
||||||
<div id = "resize-canvas">
|
<div class="update" id = "resize-canvas">
|
||||||
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
||||||
<h1>Resize canvas</h1>
|
<h1>Resize canvas</h1>
|
||||||
|
|
||||||
@ -371,6 +364,80 @@
|
|||||||
<button id = "resize-canvas-confirm">Resize canvas</button>
|
<button id = "resize-canvas-confirm">Resize canvas</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- PALETTE -->
|
||||||
|
<div id = "palette-block">
|
||||||
|
<h1>Edit palette</h1>
|
||||||
|
<!--<div id = "palette-container" onresize="updateSizeData()">
|
||||||
|
<ul id = "palette-list">
|
||||||
|
<li style = "background-color:rgb(255,0,0);width:50px;height:50px;"></li>
|
||||||
|
<li style = "background-color:rgb(0,255,0);width:50px;height:50px;"></li>
|
||||||
|
</ul>
|
||||||
|
</div>-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div id="pb-options">
|
||||||
|
<ul id = "palette-options">
|
||||||
|
<li><button title="Add colours to palette" onclick="addColours()">{{svg "plus.svg" width="15px" height="15px"}}</button></li>
|
||||||
|
<li><button title="Remove colours from palette" onclick="removeColours()">{{svg "minus.svg" width="15px" height="15px"}}</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
<div id = "colour-picker">
|
||||||
|
<div id = "cp-modes">
|
||||||
|
<button id="cp-rgb" class="cp-selected-mode" onclick="changePickerMode(this, 'rgb')">RGB</button>
|
||||||
|
<button id="cp-hsv" onclick="changePickerMode(this, 'hsv')">HSV</button>
|
||||||
|
<button id="cp-hsl" onclick="changePickerMode(this, 'hsl')">HSL</button>
|
||||||
|
|
||||||
|
<div id="cp-colour-preview" class="cp-colour-preview"></div>
|
||||||
|
<input id="cp-hex" type="text" value="#123456" onchange="hexUpdated()"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id = "sliders-container">
|
||||||
|
<div class = "cp-slider-entry">
|
||||||
|
<label for = "first-slider">R</label>
|
||||||
|
<input type="range" min="0" max="255" class="colour-picker-slider" id="first-slider" onmousemove="updateSliderValue(1)" onclick="updateSliderValue(1)"/>
|
||||||
|
<input type = "text" value = "128" onchange="inputChanged(this,1)"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class = "cp-slider-entry">
|
||||||
|
<label for = "second-slider">G</label>
|
||||||
|
<input type="range" min="0" max ="255" class="colour-picker-slider" id="second-slider" onmousemove="updateSliderValue(2)" onclick="updateSliderValue(2)"/>
|
||||||
|
<input type = "text" value = "128" onchange="inputChanged(this,2)"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class = "cp-slider-entry">
|
||||||
|
<label for = "third-slider">B</label>
|
||||||
|
<input type="range" min = "0" max = "255" class = "colour-picker-slider" id = "third-slider" onmousemove="updateSliderValue(3)" onclick="updateSliderValue(3)"/>
|
||||||
|
<input type = "text" value = "128" onchange="inputChanged(this,3)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id = "cp-minipicker">
|
||||||
|
<input type = "range" min = "0" max = "100" id = "cp-minipicker-slider" onmousemove="miniSliderInput(event)" onclick="miniSliderInput(event)"/>
|
||||||
|
<div id="cp-canvas-container" onmousemove="movePickerIcon(event)">
|
||||||
|
<canvas id = "cp-spectrum"></canvas>
|
||||||
|
<div id="cp-active-icon" class="cp-picker-icon"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id = "cp-colours-previews">
|
||||||
|
<div class = "cp-colour-preview">
|
||||||
|
#123456
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id = "cp-colour-picking-modes">
|
||||||
|
<button class="cp-selected-mode" onclick="changePickingMode(event,'mono')">Mono</button>
|
||||||
|
<button onclick="changePickingMode(event,'analog')">Anlgs</button>
|
||||||
|
<button onclick="changePickingMode(event,'cmpt')">Cmpt</button>
|
||||||
|
<button onclick="changePickingMode(event,'tri')">Tri</button>
|
||||||
|
<button onclick="changePickingMode(event,'scmpt')">Scmpt</button>
|
||||||
|
<button onclick="changePickingMode(event,'tetra')">Tetra</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="help">
|
<div id="help">
|
||||||
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
<button class="close-button">{{svg "x.svg" width="20" height="20"}}</button>
|
||||||
<h1>Help</h1>
|
<h1>Help</h1>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user