pixel-editor/js/_colorPicker.js

806 lines
28 KiB
JavaScript

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);
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();
colourPreview.style.backgroundColor = hex;
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;
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%);}";
updateMiniPickerSpectrum();
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
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 {
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);
}
}