diff --git a/README.md b/README.md index d0a42f6..2152155 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Suggestions / Planned features: - Documentation +- Possibility to hide and resize menus (layers, palette) +- What's new window to show the latest updates - Line tool - Tiled mode - Load palette from LPE file diff --git a/css/pixel-editor.scss b/css/pixel-editor.scss index 98d3b9e..f2ff702 100644 --- a/css/pixel-editor.scss +++ b/css/pixel-editor.scss @@ -125,7 +125,7 @@ body { z-index: 1120; list-style-type: none; overflow-y:scroll; - overflow-x:hidden; // TODO: make the scroll bar a bit fancier + overflow-x:hidden; #add-layer-button { path { fill: $baseicon; @@ -178,7 +178,7 @@ body { .layers-menu-entry { cursor: pointer; - margin-top: 2px; + margin-bottom: 2px; font-size: 1em; color: $basetext; 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 { float: right; 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 { background: $basehover url('/pixel-editor/dropdown-arrow.png') right center no-repeat; border: none; @@ -1038,9 +1052,9 @@ svg { input[type=number] { position:relative; margin-left:10px; - height:15px; - width:40px; - padding:8px; + height:15px !important; + width:40px !important; + padding:8px !important; } input[type=number]::-webkit-outer-spin-button, @@ -1212,4 +1226,287 @@ svg { background: $baseselected; } } +} +/***********************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; + } } \ No newline at end of file diff --git a/js/_addColor.js b/js/_addColor.js index 156fa1d..51649d1 100644 --- a/js/_addColor.js +++ b/js/_addColor.js @@ -19,6 +19,7 @@ function addColor (newColor) { button.style.backgroundColor = newColor; button.addEventListener('mouseup', clickedColor); listItem.appendChild(button); + listItem.classList.add("draggable-colour") //insert new listItem element at the end of the colors menu (right before add button) colorsMenu.insertBefore(listItem, colorsMenu.children[colorsMenu.children.length-1]); @@ -37,11 +38,21 @@ function addColor (newColor) { //hide edit button button.parentElement.lastChild.classList.add('hidden'); - //show jscolor picker - button.parentElement.firstChild.jscolor.show(); + //show jscolor picker, if basic mode is enabled + if (pixelEditorMode == 'Basic') + button.parentElement.firstChild.jscolor.show(); + else + showDialogue("palette-block", false); }); //console.log(currentPalette); return listItem; } + +new Sortable(document.getElementById("colors-menu"), { + animation:100, + filter: ".noshrink", + draggable: ".draggable-colour", + onEnd: makeIsDraggingFalse +}); \ No newline at end of file diff --git a/js/_algorithms.js b/js/_algorithms.js new file mode 100644 index 0000000..7e94fc8 --- /dev/null +++ b/js/_algorithms.js @@ -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; +} \ No newline at end of file diff --git a/js/_colorPicker.js b/js/_colorPicker.js new file mode 100644 index 0000000..7814521 --- /dev/null +++ b/js/_colorPicker.js @@ -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 -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 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); + } +} \ No newline at end of file diff --git a/js/_createColorPalette.js b/js/_createColorPalette.js index 01a502d..f490a99 100644 --- a/js/_createColorPalette.js +++ b/js/_createColorPalette.js @@ -87,5 +87,5 @@ function createPaletteFromLayers() { } //create palette form colors array - createColorPalette(colorPaletteArray, false); + //createColorPalette(colorPaletteArray, false); } \ No newline at end of file diff --git a/js/_editorMode.js b/js/_editorMode.js index 8ed2bc7..32df107 100644 --- a/js/_editorMode.js +++ b/js/_editorMode.js @@ -18,12 +18,11 @@ function switchMode(currentMode, mustConfirm = true) { // Show the layer menus layerList.style.display = "inline-block"; document.getElementById('layer-button').style.display = 'inline-block'; - // Move the palette menu - document.getElementById('colors-menu').style.right = '200px'; + // Hide the palette menu + document.getElementById('colors-menu').style.right = '200px' pixelEditorMode = 'Advanced'; } - //switch to basic mode else { //if there is a current layer (a document is active) @@ -47,8 +46,10 @@ function switchMode(currentMode, mustConfirm = true) { // Hide the layer menus layerList.style.display = 'none'; document.getElementById('layer-button').style.display = 'none'; - // Move the palette menu - document.getElementById('colors-menu').style.right = '0px'; + // Show the palette menu + document.getElementById('colors-menu').style.display = 'flex'; + // Move the palette menu + document.getElementById('colors-menu').style.right = '0px'; pixelEditorMode = 'Basic'; } diff --git a/js/_pixelEditorUtility.js b/js/_pixelEditorUtility.js index ff48c47..73fa2b8 100644 --- a/js/_pixelEditorUtility.js +++ b/js/_pixelEditorUtility.js @@ -260,4 +260,11 @@ function getPixelPosition(index) { let y = Math.floor(linearIndex / layers[0].canvasSize[0]); return [Math.ceil(x), Math.ceil(y)]; +} + +/** Sets isDragging to false, used when the user interacts with sortable lists + * + */ +function makeIsDraggingFalse(event) { + dragging = false; } \ No newline at end of file diff --git a/js/pixel-editor.js b/js/pixel-editor.js index 8f9a6ae..0faaed3 100644 --- a/js/pixel-editor.js +++ b/js/pixel-editor.js @@ -13,6 +13,7 @@ //=include libraries/cookies.js //=include _pixelEditorUtility.js //=include sortable.js +//=include _algorithms.js /**init**/ //=include _consts.js @@ -48,6 +49,7 @@ //=include _copyPaste.js //=include _resizeCanvas.js //=include _resizeSprite.js +//=include _colorPicker.js /**load file**/ //=include _loadImage.js diff --git a/views/pixel-editor.hbs b/views/pixel-editor.hbs index f4f4a81..e7d6f68 100644 --- a/views/pixel-editor.hbs +++ b/views/pixel-editor.hbs @@ -139,14 +139,7 @@
  • -
      - - {{! -
    • - }} -
    @@ -232,9 +225,9 @@ {{svg "adjust.svg" width="20" height="20" }} -
    +
    -
    +

    New Pixel

    @@ -263,7 +256,7 @@
    -
    +

    Scale sprite

    @@ -313,7 +306,7 @@
    -
    +

    Resize canvas

    @@ -371,6 +364,80 @@
    + + +
    +

    Edit palette

    + + + +
    +
    + + + + +
    + +
    + +
    +
    + + + +
    + +
    + + + +
    + +
    + + + +
    +
    + +
    + +
    + +
    +
    + +
    +
    + #123456 +
    +
    + +
    + + + + + + +
    +
    +
    +
    +

    Help