function colorDistance(color1, color2) { return Math.sqrt( Math.pow(color2._r - color1._r, 2) + Math.pow(color2._g - color1._g, 2) + Math.pow(color2._b - color1._b, 2) ); } (function() { var palettes = { default: [ '#1a1a1b','#353637','#464849','#5d5f60','#757677','#868788','#979b9d','#b8bdbe','#dadedf','#ffffff', '#9a080f','#b40a1a','#d21129','#ef2142','#ff5774','#bb7907','#cc9104','#edb508','#fcd720','#fef364', '#0d7e36','#12933d','#11aa38','#1cc93d','#29e64d','#044b8f','#0955a8','#126bc3','#1782db','#339afc', '#cd3e00','#e65b00','#f37800','#f89520','#fdaf40','#02a8c1','#0cc3ca','#17d1c7','#38debd','#5be9b7', ], material: [ '#ffebee','#ffcdd2','#ef9a9a','#e57373','#ef5350','#f44336','#e53935','#d32f2f','#c62828','#b71c1c','#ff5252','#ff1744', '#fce4ec','#f8bbd0','#f48fb1','#f06292','#ec407a','#e91e63','#d81b60','#c2185b','#ad1457','#880e4f','#ff4081','#f50057', '#f3e5f5','#e1bee7','#ce93d8','#ba68c8','#ab47bc','#9c27b0','#8e24aa','#7b1fa2','#6a1b9a','#4a148c','#e040fb','#d500f9', '#ede7f6','#d1c4e9','#b39ddb','#9575cd','#7e57c2','#673ab7','#5e35b1','#512da8','#4527a0','#311b92','#7c4dff','#651fff', '#e8eaf6','#c5cae9','#9fa8da','#7986cb','#5c6bc0','#3f51b5','#3949ab','#303f9f','#283593','#1a237e','#536dfe','#3d5afe', '#e3f2fd','#bbdefb','#90caf9','#64b5f6','#42a5f5','#2196f3','#1e88e5','#1976d2','#1565c0','#0d47a1','#448aff','#2979ff', '#e1f5fe','#b3e5fc','#81d4fa','#4fc3f7','#29b6f6','#03a9f4','#039be5','#0288d1','#0277bd','#01579b','#40c4ff','#00b0ff', '#e0f7fa','#b2ebf2','#80deea','#4dd0e1','#26c6da','#00bcd4','#00acc1','#0097a7','#00838f','#006064','#18ffff','#00e5ff', '#e0f2f1','#b2dfdb','#80cbc4','#4db6ac','#26a69a','#009688','#00897b','#00796b','#00695c','#004d40','#64ffda','#1de9b6', '#e8f5e9','#c8e6c9','#a5d6a7','#81c784','#66bb6a','#4caf50','#43a047','#388e3c','#2e7d32','#1b5e20','#69f0ae','#00e676', '#f1f8e9','#dcedc8','#c5e1a5','#aed581','#9ccc65','#8bc34a','#7cb342','#689f38','#558b2f','#33691e','#b2ff59','#76ff03', '#f9fbe7','#f0f4c3','#e6ee9c','#dce775','#d4e157','#cddc39','#c0ca33','#afb42b','#9e9d24','#827717','#eeff41','#c6ff00', '#fffde7','#fff9c4','#fff59d','#fff176','#ffee58','#ffeb3b','#fdd835','#fbc02d','#f9a825','#f57f17','#ffff00','#ffea00', '#fff8e1','#ffecb3','#ffe082','#ffd54f','#ffca28','#ffc107','#ffb300','#ffa000','#ff8f00','#ff6f00','#ffd740','#ffc400', '#fff3e0','#ffe0b2','#ffcc80','#ffb74d','#ffa726','#ff9800','#fb8c00','#f57c00','#ef6c00','#e65100','#ffab40','#ff9100', '#fbe9e7','#ffccbc','#ffab91','#ff8a65','#ff7043','#ff5722','#f4511e','#e64a19','#d84315','#bf360c','#ff6e40','#ff3d00', '#efebe9','#d7ccc8','#bcaaa4','#a1887f','#8d6e63','#795548','#6d4c41','#5d4037','#4e342e','#3e2723','#6d422d','#593022', '#fafafa','#f5f5f5','#eeeeee','#e0e0e0','#bdbdbd','#9e9e9e','#757575','#616161','#424242','#212121','#ffffff','#000000', '#eceff1','#cfd8dc','#b0bec5','#90a4ae','#78909c','#607d8b','#546e7a','#455a64','#37474f','#263238', ], endesga64: [ '#ff0040','#131313','#1b1b1b','#272727','#3d3d3d','#5d5d5d','#858585','#b4b4b4','#ffffff','#c7cfdd', '#92a1b9','#657392','#424c6e','#2a2f4e','#1a1932','#0e071b','#1c121c','#391f21','#5d2c28','#8a4836', '#bf6f4a','#e69c69','#f6ca9f','#f9e6cf','#edab50','#e07438','#c64524','#8e251d','#ff5000','#ed7614', '#ffa214','#ffc825','#ffeb57','#d3fc7e','#99e65f','#5ac54f','#33984b','#1e6f50','#134c4c','#0c2e44', '#00396d','#0069aa','#0098dc','#00cdf9','#0cf1ff','#94fdff','#fdd2ed','#f389f5','#db3ffd','#7a09fa', '#3003d9','#0c0293','#03193f','#3b1443','#622461','#93388f','#ca52c9','#c85086','#f68187','#f5555d', '#ea323c','#c42430','#891e2b','#571c27', ] } Interface.definePanels(() => { ColorPanel = Interface.Panels.color = new Panel({ id: 'color', icon: 'palette', condition: () => Modes.id === 'paint', toolbars: { picker: Toolbars.color_picker, palette: Toolbars.palette }, onResize: t => { $('#main_colorpicker').spectrum('reflow'); }, menu: new Menu([ 'sort_palette', 'load_palette' ]) }) var saved_colors = localStorage.getItem('colors'); if (saved_colors) { try { saved_colors = JSON.parse(saved_colors); } catch (err) { saved_colors = null; } } ColorPanel.updateFromHsv = function() { ColorPanel.change({ h: ColorPanel.vue._data.hsv.h, s: ColorPanel.vue._data.hsv.s/100, v: ColorPanel.vue._data.hsv.v/100 }); } ColorPanel.hexToHsv = function(hex) { var color = new tinycolor(hex); var tc = color.toHsv(); return {h: tc.h, s: tc.s*100, v: tc.v*100}; } Interface.Panels.color.vue = new Vue({ el: '#color_panel_wrapper', data: { open_tab: 'picker', main_color: '#000000', hover_color: '', get color_code() {return this.hover_color || this.main_color}, set color_code(color) { this.main_color = color.toLowerCase().replace(/[^a-f0-9#]/g, ''); }, text_input: '#000000', hsv: { h: 0, s: 0, v: 0, }, palette: (saved_colors && saved_colors.palette instanceof Array) ? saved_colors.palette : palettes.default.slice(), history: (saved_colors && saved_colors.history instanceof Array) ? saved_colors.history : [] }, methods: { sort(event) { var index = event.oldIndex; var item = this.palette.splice(event.oldIndex, 1)[0]; this.palette.splice(event.newIndex, 0, item); }, drop: function(event) { /* var scope = this; setTimeout(() => { if ($('#palette_list:hover').length === 0) { scope.palette.splice(event.oldIndex, 1)[0] } }, 30) */ }, setColor(color) { ColorPanel.set(color); }, validateMainColor() { var color = this.main_color; if (!color.match(/^#[0-9a-f]{6}$/)) { this.main_color = tinycolor(color).toHexString(); } }, isDarkColor(hex) { if (hex) { hex = hex.replace('#', '') let dgts = hex.substr(0, 1) + hex.substr(2, 1) + hex.substr(4, 1) let bg = parseInt(CustomTheme.data.colors.back.substr(1, 1), 16); let color_range = (bg).toString(16) + (Math.isBetween(bg+2, 0, 15) ? (bg+2).toString(16) : '') + (Math.isBetween(bg+1, 0, 15) ? (bg+1).toString(16) : '') + (Math.isBetween(bg-1, 0, 15) ? (bg-1).toString(16) : '') + (Math.isBetween(bg-2, 0, 15) ? (bg-2).toString(16) : '') let regex = new RegExp(`[^${color_range}]`) return dgts.search(regex) == -1 } } }, watch: { main_color: function(value) { this.hover_color = ''; Object.assign(this.hsv, ColorPanel.hexToHsv(value)); BarItems.slider_color_h.update(); BarItems.slider_color_s.update(); BarItems.slider_color_v.update(); $('#main_colorpicker').spectrum('set', value); this.text_input = value; } } }) ColorPanel.palette = Interface.Panels.color.vue._data.palette; ColorPanel.addToHistory = function(color) { color = color.toLowerCase(); var history = ColorPanel.vue._data.history; if (color == history[0]) return; if (color.match(/#[a-f0-9]{6}/g)) { var max = 18; history.remove(color); history.splice(0, 0, color); if (history.length > max) history.length = max; $('#color_history')[0].scrollLeft = 0; } } ColorPanel.change = function(color) { var value = new tinycolor(color) ColorPanel.vue._data.main_color = value.toHexString(); } ColorPanel.set = function(color, no_sync) { ColorPanel.change(color) ColorPanel.addToHistory(ColorPanel.vue._data.main_color) if (!no_sync && isApp && settings.sync_color.value) { ipcRenderer.send('change-main-color', ColorPanel.vue._data.main_color); } } ColorPanel.get = function() { ColorPanel.addToHistory(ColorPanel.vue._data.main_color); return ColorPanel.vue._data.main_color; } Interface.Panels.color.picker = $('#main_colorpicker').spectrum({ preferredFormat: "hex", color: 'ffffff', flat: true, localStorageKey: 'brush_color_palette', move: function(c) { ColorPanel.change(c) } }) $('#color_history').on('mousewheel', function(e) { var current = this.scrollLeft; var delta = (e.originalEvent.deltaY < 0 ? -90 : 90); this.scrollLeft += delta; //$(this).animate({scrollLeft: current + delta}, 200) }) if (isApp) { ipcRenderer.on('set-main-color', (event, arg) => { ColorPanel.set(arg, true); }) } ColorPanel.importPalette = function(file) { let extension = pathToExtension(file.path); if (extension == 'png') { var img = new Image(file.content); img.src = file.content || file.path; img.onload = function() { var c = document.createElement('canvas'); var ctx = c.getContext('2d'); c.width = img.naturalWidth; c.height = img.naturalHeight; ctx.drawImage(img, 0, 0); ColorPanel.generatePalette(ctx, false); } return; } var colors = []; if (extension === 'ase') { let colorContents = file.content; let colorBuffer = Buffer.from(colorContents); let signature = colorBuffer.toString('utf-8', 0, 4); let versionMajor = colorBuffer.slice(4, 6).readInt16BE(0); let versionMin = colorBuffer.slice(6, 8).readInt16BE(0); let count = colorBuffer.slice(8, 12).readInt32BE(0); if (colorBuffer.length > 12 && signature !== 'ASEF' && versionMajor !== 1 && versionMin !== 0) { console.log('Invalid ASE swatch file'); return; } let i = 12; while (i < colorBuffer.length) { let blockLength; let blockType = colorBuffer.slice(i, i + 2).readInt16BE(0).toString(16); i += 2; // Ignore group start c001, end c002 if (blockType === 'c001') { blockLength = colorBuffer.slice(i, i + 4).readInt32BE(0); i += blockLength; } if (blockType === 'c002') { i += 2; } // Color entry, start 0001 if (blockType === '1') { blockLength = colorBuffer.slice(i, i + 4).readInt32BE(0); let nameLength = colorBuffer.slice(i + 4, i + 6).readUInt16BE(0); let colorName = ''; let color; for (let j = 0; j < nameLength * 2 - 2; j += 2) { colorName += String.fromCodePoint(colorBuffer.slice(i + 6 + j, i + 8 + j).readInt16BE(0)); } let _i = i + 6 + nameLength * 2; let colorModel = colorBuffer.slice(_i, _i + 4).toString('utf-8', 0, 4); _i += 4; if (colorModel === 'RGB ') { let r = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let g = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let b = colorBuffer.slice(_i, _i + 4).readFloatBE(0); color = new tinycolor({r: r*255, g: g*255, b: b*255}) //nscolor = color.colorWithRGBA(r * 255, g * 255, b * 255, 1.0); } else if (colorModel === 'CMYK') { let c = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let m = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let y = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let k = colorBuffer.slice(_i, _i + 4).readFloatBE(0); //nscolor = color.colorWithCMYKA(c * 100, m * 100, y * 100, k * 100, 1.0); color = new tinycolor({ r: 255 * (1 - c) * (1 - k), g: 255 * (1 - m) * (1 - k), b: 255 * (1 - y) * (1 - k) }) } else if (colorModel === 'LAB ') { let l = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let a = colorBuffer.slice(_i, _i + 4).readFloatBE(0); _i += 4; let b = colorBuffer.slice(_i, _i + 4).readFloatBE(0); //nscolor = color.colorWithLABA(l * 100, a * 100, b * 100, 1.0); } else if (colorModel === 'Gray') { let g = colorBuffer.slice(_i, _i + 4).readFloatBE(0); color = new tinycolor({r: g*255, g: g*255, b: g*255}) } colors.push(color.toHexString()); i += blockLength; } } } else if (extension === 'aco') { let colorContents = file.content; let colorBuffer = Buffer.from(colorContents); if (colorBuffer.length < 4) { UI.message('Invalid ACO file'); return; } let version = colorBuffer.slice(0, 2).readUInt16BE(0); let count = colorBuffer.slice(2, 4).readUInt16BE(0); // version 1 let i; if (version === 1 && (colorBuffer.length - 4) / 10 === count) { i = 4; while (i < colorBuffer.length) { let colorSpace = colorBuffer.slice(i, i + 2).readUInt16BE(0); let r = colorBuffer.slice(i + 2, i + 4).readUInt16BE(0); let g = colorBuffer.slice(i + 4, i + 6).readUInt16BE(0); let b = colorBuffer.slice(i + 6, i + 8).readUInt16BE(0); let z = colorBuffer.slice(i + 8, i + 10).readUInt16BE(0); if (colorSpace === 0) { let color = new tinycolor({ r: Math.floor(r/255), g: Math.floor(g/255), b: Math.floor(b/255) }) colors.push(color.toHexString()); } i += 10; } } // version 2 if ( (version === 2) || ( version === 1 && colorBuffer.length > count * 10 + 8 && colorBuffer.slice(4 + count * 10, 6 + count * 10).readUInt16BE(0) === 2 && colorBuffer.slice(6 + count * 10, 8 + count * 10).readUInt16BE(0) === count ) ) { i = 4 + count * 10 + 4; if (version === 2) { i = 4; } while (i < colorBuffer.length) { let colorSpace = colorBuffer.slice(i, i + 2).readUInt16BE(0); let r = colorBuffer.slice(i + 2, i + 4).readUInt16BE(0); let g = colorBuffer.slice(i + 4, i + 6).readUInt16BE(0); let b = colorBuffer.slice(i + 6, i + 8).readUInt16BE(0); let z = colorBuffer.slice(i + 8, i + 10).readUInt16BE(0); let colorName = ''; let nameLength = colorBuffer.slice(i + 12, i + 14).readUInt16BE(0); /*for (let j = 0; j < nameLength * 2 - 2; j += 2) { colorName += String.fromCodePoint(colorBuffer.slice(i + 14 + j, i + 16 + j).readUInt16BE(0)); }*/ // colorspace: [0: RGB, 1: HSB (hsv), 2: CMYK, 7: Lab, 8: Gray] if (colorSpace === 0) { let color = new tinycolor({ r: Math.floor(r/255), g: Math.floor(g/255), b: Math.floor(b/255) }) colors.push(color.toHexString()); } i += 14 + nameLength * 2; } } } else if (extension === 'act') { let colorContents = file.content; let colorBuffer = Buffer.from(colorContents); let maxLength = Math.min(colorBuffer.length, 768); if (colorBuffer.length === 772) { maxLength = colorBuffer[769]*3 } for (var i = 0; i < maxLength; i += 3) { let color = new tinycolor({ r: colorBuffer[i+0], g: colorBuffer[i+1], b: colorBuffer[i+2] }) colors.push(color); } } else { var string = file.content; var m_hex = string.match(/(#|FF)?[a-fA-F0-9]{6}/g); if (m_hex) m_hex.forEach(color => { color = color.substr(-6).toLowerCase(); colors.safePush('#'+color); }) var m_rgb = string.match(/\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}\s*\)/g) if (m_rgb) m_rgb.forEach(color => { color = tinycolor('rgb'+color); colors.safePush(color.toHexString()); }) var m_gpl = string.match(/\n\d{1,3} \d{1,3} \d{1,3}/g) if (m_gpl) m_gpl.forEach(color => { color = tinycolor(`rgb(${color.substr(1).replace(/ /g, ',')})`); colors.safePush(color.toHexString()); }) var m_gpl = string.match(/\n\d{1,3} \d{1,3} \d{1,3}/g) if (m_gpl) m_gpl.forEach(color => { color = tinycolor(`rgb(${color.substr(1).replace(/ /g, ',')})`); colors.safePush(color.toHexString()); }) } if (ColorPanel.palette.length) { var dialog = new Dialog({ id: 'palette_import', title: 'action.import_palette', width: 400, form: { replace: {label: 'message.import_palette.replace_palette', type: 'checkbox', value: true}, }, onConfirm(formData) { if (formData.replace) { ColorPanel.palette.purge(); ColorPanel.palette.push(...colors); } else { colors.forEach(color => { ColorPanel.palette.safePush(color); }) } dialog.hide(); } }); dialog.show(); } else { colors.forEach(color => { ColorPanel.palette.push(color); }) } } ColorPanel.generatePalette = function(source, process_colors = true) { var options = {}; if (!source) { textures.forEach((tex, i) => { if (!tex.error) { options[i] = tex.name; } }) } var dialog = new Dialog({ id: 'generate_palette', title: 'action.import_palette', width: 460, form: { texture: {label: 'data.texture', type: 'select', options, condition: !source}, replace: {label: 'message.import_palette.replace_palette', type: 'checkbox', value: true}, threshold: {label: 'message.import_palette.threshold', type: 'number', value: 10, min: 0, max: 100, condition: process_colors}, }, onConfirm(formData) { var colors = {}; var result_palette = []; if (!source) { var texture = textures[formData.texture]; var ctx = Painter.getCanvas(texture).getContext('2d'); } else { var ctx = source; } Painter.scanCanvas(ctx, 0, 0, ctx.canvas.width, ctx.canvas.height, (x, y, px) => { if (px[3] < 12) return; var t = tinycolor({ r: px[0], g: px[1], b: px[2] }) var hex = t.toHexString(); if (colors[hex]) { colors[hex].count++; } else { colors[hex] = t; t.count = 1; } }) if (process_colors) { var pots = {gray:[], red:[], orange:[], yellow:[], green:[], blue:[], magenta:[]} for (var hex in colors) { var color = colors[hex]; if (Math.abs(color._r - color._g) + Math.abs(color._g - color._b) + Math.abs(color._r - color._b) < 74) { //gray pots.gray.push(color); } else { var distances = { red: colorDistance(color, {_r: 250, _g: 0, _b: 0}), orange: colorDistance(color, {_r: 240, _g: 127, _b: 0})*1.4, yellow: colorDistance(color, {_r: 265, _g: 240, _b: 0})*1.4, green: colorDistance(color, {_r: 0, _g: 255, _b: 0}), blue: colorDistance(color, {_r: 0, _g: 50, _b: 240}), magenta: colorDistance(color,{_r: 255, _g: 0, _b: 255})*1.4, } var closest = highestInObject(distances, true); pots[closest].push(color); } } for (var pot in pots) { pots[pot].sort((a, b) => { return (a._r + a._g + a._b) - (b._r + b._g + b._b); }) if (pots[pot].length > 1) { for (var i = pots[pot].length-2; i >= 0; i--) { var col = pots[pot][i]; var abv = pots[pot][i+1]; var distance = colorDistance(col, abv); if (distance < formData.threshold) { if (col.count < col.count) { pots[pot].splice(i, 1); } else { pots[pot].splice(i+1, 1); } } } } pots[pot].forEach(color => { result_palette.push(color.toHexString()); }) } } else { for (var hex in colors) { result_palette.push(hex); } } if (formData.replace) { ColorPanel.palette.purge(); ColorPanel.palette.push(...result_palette); } else { result_palette.forEach(color => { ColorPanel.palette.safePush(color); }) } dialog.hide(); } }); dialog.show(); } Blockbench.addDragHandler('palette', { extensions: ['gpl', 'css', 'txt', 'hex', 'png', 'aco', 'act', 'ase', 'bbpalette'], readtype: 'text', readtype: (path) => { switch (pathToExtension(path)) { case 'png': return 'image'; break; case 'ase': return 'binary'; break; case 'act': return 'binary'; break; case 'aco': return 'binary'; break; default: return 'text'; break; }}, element: '#color', propagate: true, }, function(files) { if (files && files[0]) { ColorPanel.importPalette(files[0]); } }) Toolbars.palette.toPlace(); Toolbars.color_picker.toPlace(); }) BARS.defineActions(function() { new Action('add_to_palette', { icon: 'add', category: 'color', click: function () { var color = ColorPanel.get(); if (!ColorPanel.palette.includes(color)) { ColorPanel.palette.push(color); Blockbench.showQuickMessage('message.add_to_palette') } } }) new Action('import_palette', { icon: 'palette', category: 'color', click: function () { Blockbench.import({ resource_id: 'palette', extensions: ['gpl', 'css', 'txt', 'hex', 'png', 'aco', 'act', 'ase', 'bbpalette'], type: 'Blockbench Palette', readtype: (path) => { switch (pathToExtension(path)) { case 'png': return 'image'; break; case 'ase': return 'binary'; break; case 'act': return 'binary'; break; case 'aco': return 'binary'; break; default: return 'text'; break; }}, }, function(files) { if (files && files[0]) { ColorPanel.importPalette(files[0]); } }) } }) new Action('export_palette', { icon: 'fas.fa-dice-four', category: 'color', click: function () { let content = 'GIMP Palette\nName: Blockbench palette\nColumns: 10\n'; ColorPanel.palette.forEach(color => { t = new tinycolor(color); content += `${t._r}\t${t._g}\t${t._b}\t${color}\n`; }) Blockbench.export({ resource_id: 'palette', extensions: ['gpl'], type: 'GPL Palette', content }, (path) => { Blockbench.showQuickMessage(tl('message.save_file', pathToName(path))); }) } }) new Action('generate_palette', { icon: 'blur_linear', category: 'color', click: function () { ColorPanel.generatePalette(); } }) new Action('sort_palette', { icon: 'fa-sort-amount-down', category: 'color', click: function () { var colors = {}; ColorPanel.palette.forEach(color => { colors[color] = tinycolor(color); }) ColorPanel.palette.empty(); var pots = {gray:[], red:[], orange:[], yellow:[], green:[], blue:[], magenta:[]} for (var hex in colors) { var color = colors[hex]; if (Math.abs(color._r - color._g) + Math.abs(color._g - color._b) + Math.abs(color._r - color._b) < 74) { //gray pots.gray.push(color); } else { var distances = { red: colorDistance(color, {_r: 250, _g: 0, _b: 0}), orange: colorDistance(color, {_r: 240, _g: 127, _b: 0})*1.4, yellow: colorDistance(color, {_r: 265, _g: 240, _b: 0})*1.4, green: colorDistance(color, {_r: 0, _g: 255, _b: 0}), blue: colorDistance(color, {_r: 0, _g: 50, _b: 240}), magenta: colorDistance(color,{_r: 255, _g: 0, _b: 255})*1.4, } var closest = highestInObject(distances, true); pots[closest].push(color); } } for (var pot in pots) { pots[pot].sort((a, b) => { return (a._r + a._g + a._b) - (b._r + b._g + b._b); }) pots[pot].forEach(color => { ColorPanel.palette.push(color.toHexString()); }) } } }) new Action('load_palette', { icon: 'fa-tasks', category: 'color', click: function (e) { new Menu(this.children).open(e.target) }, children: [ {name: 'menu.palette.load.default', icon: 'bubble_chart', id: 'default', click: () => { ColorPanel.palette.splice(0, Infinity, ...palettes.default); }}, {name: 'Endesga 64', description: 'Pixel art palette created by lospec.com/endesga', icon: 'bubble_chart', id: 'endesga64', click: () => { ColorPanel.palette.splice(0, Infinity, ...palettes.endesga64); }}, {name: 'Material', icon: 'bubble_chart', id: 'material', click: () => { ColorPanel.palette.splice(0, Infinity, ...palettes.material); }}, '_', {name: 'menu.palette.load.empty', icon: 'clear', id: 'empty', click: () => { ColorPanel.palette.splice(0, Infinity); }}, ] }) new NumSlider('slider_color_h', { condition: () => Modes.paint, category: 'color', settings: { min: 0, max: 360, default: 0, }, getInterval(e) { if (e.shiftKey) return 12.5; if (e.ctrlKey) return 1; return 4 }, get: function() { return Math.round(ColorPanel.vue._data.hsv.h); }, change: function(modify) { var value = modify(ColorPanel.vue._data.hsv.h); ColorPanel.vue._data.hsv.h = Math.clamp(value, this.settings.min, this.settings.max); ColorPanel.updateFromHsv(); } }) new NumSlider('slider_color_s', { condition: () => Modes.paint, category: 'color', settings: { min: 0, max: 100, default: 0, }, getInterval(e) { if (e.shiftKey) return 10; if (e.ctrlKey) return 1; return 2 }, get: function() { return Math.round(ColorPanel.vue._data.hsv.s); }, change: function(modify) { var value = modify(ColorPanel.vue._data.hsv.s); ColorPanel.vue._data.hsv.s = Math.clamp(value, this.settings.min, this.settings.max); ColorPanel.updateFromHsv(); } }) new NumSlider('slider_color_v', { condition: () => Modes.paint, category: 'color', settings: { min: 0, max: 100, default: 100, }, getInterval(e) { if (e.shiftKey) return 10; if (e.ctrlKey) return 1; return 2 }, get: function() { return Math.round(ColorPanel.vue._data.hsv.v); }, change: function(modify) { var value = modify(ColorPanel.vue._data.hsv.v); ColorPanel.vue._data.hsv.v = Math.clamp(value, this.settings.min, this.settings.max); ColorPanel.updateFromHsv(); } }) }) })()