From f421a344b1b48926a2ca25bb43727a741a24356f Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sun, 31 Mar 2024 10:11:51 +0200 Subject: [PATCH] add color picker for audio min max dependencies hashes: openFrameworks d78075f4bca6be2a2533c6e51a75cc1f18404501 ofxMsdfgen e14da13d02c4dff04fb69d7923469f606924e6c3 ofxGPUFont d482bb7cbdf6b296fa4ab5abcf73fb5ff8c8b239 ofxVariableLab 0b5f9bdebc1e5550621957e73c040c258ec6317b ofxProfiler a868e34fa1a79189dd4fbdede2938e308535e5e8 theatre 86d3e07f6f2c75fd6e08fca8c97e3617c9e23b18 --- assets/template.html | 1 + bin/em/variabletime/web/css/theatre.css | 5 + bin/em/variabletime/web/js/audio.js | 182 ++-- bin/em/variabletime/web/js/config.js | 4 +- bin/em/variabletime/web/js/theatre-play.js | 1 + bin/em/variabletime/web/js/utils.js | 55 +- bin/em/variabletime/web/js/vanilla-picker.js | 1009 ++++++++++++++++++ browser.sh | 3 + 8 files changed, 1189 insertions(+), 71 deletions(-) create mode 100644 bin/em/variabletime/web/js/vanilla-picker.js diff --git a/assets/template.html b/assets/template.html index 1f6a2bc..e5eddab 100644 --- a/assets/template.html +++ b/assets/template.html @@ -576,6 +576,7 @@ }; + diff --git a/bin/em/variabletime/web/css/theatre.css b/bin/em/variabletime/web/css/theatre.css index e5fdf51..e7e2a83 100644 --- a/bin/em/variabletime/web/css/theatre.css +++ b/bin/em/variabletime/web/css/theatre.css @@ -552,3 +552,8 @@ li.layerMover div.selected svg circle { .panelMomWrapper { overflow-x: hidden; } + +/* ASYA: color picker can be changed like this */ +.picker_wrapper.popup .picker_arrow::before { + /*background: pink;*/ +} diff --git a/bin/em/variabletime/web/js/audio.js b/bin/em/variabletime/web/js/audio.js index 5f62997..189e251 100644 --- a/bin/em/variabletime/web/js/audio.js +++ b/bin/em/variabletime/web/js/audio.js @@ -1,10 +1,13 @@ import { mapValue, + smoothValue, mix, toCssClass, flattenObject, deFlattenObject, clone, + rgbaToHexa, + hexaToRgba, } from './utils.js'; window.mapValue = mapValue; @@ -122,6 +125,9 @@ const Audio = function(tp, record) { } else if (propTitle.split('.')[0] === 'fontVariationAxes') { return layer.props.fontVariationAxes .props[propTitle.split('.')[1]].range; + } else { + console.error('Audio::getDefaultRange', 'propTitle not recognized', {propTitle}); + return false; } }; @@ -133,31 +139,10 @@ const Audio = function(tp, record) { return m; } return savedMapping[layer.id()][propTitle]; - } else if (propTitle === 'color') { - const mm = getDefaultRange(layer, 'color'); - if (config.audio.colorSeparateRGBA) { - const r = new AudioMappingOptions(); - r.min_out = mm[0]; - r.max_out = mm[1]; - const g = new AudioMappingOptions(); - g.min_out = mm[0]; - g.max_out = mm[1]; - const b = new AudioMappingOptions(); - b.min_out = mm[0]; - b.max_out = mm[1]; - const a = new AudioMappingOptions(); - a.min_out = 1.0; // NOTE: dirty, dirty - a.max_out = 1.0; // hardcoded value, you - return [{r}, {g}, {b}, {a}]; - } else { - const o = new AudioMappingOptions(); - o.min_out = {r: mm[0], b: mm[0], g: mm[0], a: mm[0]}; - o.max_out = {r: mm[1], b: mm[1], g: mm[1], a: mm[1]}; - return o; - } } else { const o = new AudioMappingOptions(); const mm = getDefaultRange(layer, propTitle); + o.value = mm[0]; // hmmmm o.min_out = mm[0]; o.max_out = mm[1]; return o; @@ -207,14 +192,14 @@ const Audio = function(tp, record) { if (!mapping[layer.id()].hasOwnProperty(propTitle)) { // no propTitle // perhaps color? - if (config.audio.colorSeparateRGBA && propTitle === 'color') { - let isGood = true; - isGood = removeAudioMapping(layer, 'color.r'); - isGood = removeAudioMapping(layer, 'color.g'); - isGood = removeAudioMapping(layer, 'color.b'); - isGood = removeAudioMapping(layer, 'color.a'); - return isGood; - } + //if (config.audio.colorSeparateRGBA && propTitle === 'color') { + //let isGood = true; + //isGood = removeAudioMapping(layer, 'color.r'); + //isGood = removeAudioMapping(layer, 'color.g'); + //isGood = removeAudioMapping(layer, 'color.b'); + //isGood = removeAudioMapping(layer, 'color.a'); + //return isGood; + //} return false; } delete mapping[layer.id()][propTitle]; @@ -243,35 +228,21 @@ const Audio = function(tp, record) { audioOptions.classList.add(toCssClass(`audioOptions${propTitle}`)); audioOptions.style.position = 'relative'; audioOptions.style.width = '100%'; - if (propTitle.split('.')[0] === 'color' && propTitle.split('.').length > 1) { - audioOptions.classList.add(toCssClass('audioOptionscolor')); - switch(propTitle.split('.')[1]) { - case 'r': { - audioOptions.style.background = config.audio.colors.options_r_background; - break; - } - case 'g': { - audioOptions.style.background = config.audio.colors.options_g_background; - break; - } - case 'b': { - audioOptions.style.background = config.audio.colors.options_b_background; - break; - } - case 'a': { - audioOptions.style.background = config.audio.colors.options_a_background; - break; - } - } - } else { - audioOptions.style.background = config.audio.colors.options_background; // AUDIO COLOR - - } + audioOptions.style.background = config.audio.colors.options_background; // AUDIO COLOR audioOptions.style.order = parseInt(container.style.order) + 1; const updateMappingOptions = () => { - mappingOptions.min_out = parseFloat(panel.querySelector(toCssClass(`audio_min${propTitle}`,'#')).value); - mappingOptions.max_out = parseFloat(panel.querySelector(toCssClass(`audio_max${propTitle}`,'#')).value); + if (propTitle === 'color') { + mappingOptions.min_out = hexaToRgba(panel.querySelector(toCssClass(`audio_min${propTitle}`,'#')).value); + const max_cssClass = toCssClass(`audio_max${propTitle}`,'#'); + const max_inputDom = panel.querySelector(max_cssClass); + const max_value = max_inputDom.value; + const max_rgba = hexaToRgba(max_value); + mappingOptions.max_out = max_rgba; + } else { + mappingOptions.min_out = parseFloat(panel.querySelector(toCssClass(`audio_min${propTitle}`,'#')).value); + mappingOptions.max_out = parseFloat(panel.querySelector(toCssClass(`audio_max${propTitle}`,'#')).value); + } mappingOptions.sync = panel.querySelector(`input[name="${toCssClass('audio_sync' + propTitle)}"]:checked`).value; const s = panel.querySelector(toCssClass(`audio_smoothing${propTitle}`,'#')).value; @@ -379,26 +350,102 @@ const Audio = function(tp, record) { min_inputDom_label.for = 'audio_min'; min_inputDom_label.innerHTML = 'min '; const min_inputDom = document.createElement('input'); - min_inputDom.type = 'number'; + if (propTitle === 'color') { + min_inputDom.type = 'text'; + min_inputDom.value = `${rgbaToHexa(mappingOptions.min_out)}`; + const min_preview = document.createElement('div'); + min_preview.classList.add('color_preview'); + min_preview.style.width = '25px'; + min_preview.style.height = '25px'; + min_preview.style.borderRadius = '50%'; + min_preview.style.border = '1px solid black'; + min_preview.style.background = min_inputDom.value; + min_Cont.append(min_preview); + const picker = new Picker({ + 'parent': min_preview, + 'color': min_inputDom.value, + 'popup': 'bottom', + }); + picker.onChange = (color) => { + min_preview.style.background = color.rgbaString; + min_inputDom.value = color.hex; + updateMappingOptions(); + //mappingOptions.min_out = { + //r: color.rgba[0] / 255, + //g: color.rgba[1] / 255, + //b: color.rgba[2] / 255, + //a: color.rgba[3], + //}; + }; + min_inputDom.addEventListener('focus', () => { + picker.show(); + min_preview.querySelector('.picker_editor input').focus(); + }); + min_inputDom.addEventListener('click', () => { + picker.show(); + min_preview.querySelector('.picker_editor input').focus(); + }); + } else { + min_inputDom.type = 'number'; + min_inputDom.value = `${mappingOptions.min_out}`; + } min_inputDom.name = toCssClass(`audio_min${propTitle}`); min_inputDom.id = toCssClass(`audio_min${propTitle}`); if (Array.isArray(defaultRange) && defaultRange.length >= 2) { - min_inputDom.title = `default: ${defaultRange[0]}`; + min_inputDom.title = `default: ${JSON.stringify(defaultRange[0])}`; } - min_inputDom.value = `${mappingOptions.min_out}`; const max_Cont = document.createElement('div'); max_Cont.classList.add('audio_max_Cont'); const max_inputDom_label = document.createElement('label'); max_inputDom_label.for = 'audio_max'; max_inputDom_label.innerHTML = 'max '; const max_inputDom = document.createElement('input'); - max_inputDom.type = 'number'; + if (propTitle === 'color') { + max_inputDom.type = 'text'; + max_inputDom.value = `${rgbaToHexa(mappingOptions.max_out)}`; + + const max_preview = document.createElement('div'); + max_preview.classList.add('color_preview'); + max_preview.style.width = '25px'; + max_preview.style.height = '25px'; + max_preview.style.borderRadius = '50%'; + max_preview.style.border = '1px solid black'; + max_preview.style.background = max_inputDom.value; + max_Cont.append(max_preview); + const picker = new Picker({ + 'parent': max_preview, + 'color': max_inputDom.value, + 'popup': 'bottom', + }); + picker.onChange = (color) => { + max_preview.style.background = color.rgbaString; + max_inputDom.value = color.hex; + updateMappingOptions(); + //mappingOptions.max_out = { + //r: color.rgba[0] / 255, + //g: color.rgba[1] / 255, + //b: color.rgba[2] / 255, + //a: color.rgba[3], + //}; + }; + max_inputDom.addEventListener('focus', () => { + picker.show(); + max_preview.querySelector('.picker_editor input').focus(); + }); + max_inputDom.addEventListener('click', () => { + picker.show(); + max_preview.querySelector('.picker_editor input').focus(); + }); + + } else { + max_inputDom.type = 'number'; + max_inputDom.value = `${mappingOptions.max_out}`; + } max_inputDom.name = toCssClass(`audio_max${propTitle}`); max_inputDom.id = toCssClass(`audio_max${propTitle}`); if (Array.isArray(defaultRange) && defaultRange.length >= 2) { - max_inputDom.title = `default: ${defaultRange[1]}`; + max_inputDom.title = `default: ${JSON.stringify(defaultRange[1])}`; } - max_inputDom.value = `${mappingOptions.max_out}`; const smoothing_inputDom_label = document.createElement('label'); smoothing_inputDom_label.for = 'audio_smoothing'; smoothing_inputDom_label.innerHTML = 'audio smoothing'; @@ -679,6 +726,7 @@ const Audio = function(tp, record) { } addAudioMapping(layer, propTitle); addAudioOptions(layer, propTitle); + layer.updateValuesViaTheatre(false); }; const removeAudio = (layer, propTitle) => { @@ -1106,7 +1154,7 @@ const Audio = function(tp, record) { switch (m.sync) { case 'volume': { let a = mapValue(m.max_v, m.min_in, m.max_in, m.min_out, m.max_out, true); - m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a; + m.value = smoothValue(m.value, a, m.smoothing); propsToSet.push({ id: layerID, title: propTitle, @@ -1121,7 +1169,7 @@ const Audio = function(tp, record) { const fi = config.audio.pitchCombineFrequencies ? ri : mi; let a = mapValue(fi, m.min_freq, m.max_freq, m.min_out, m.max_out, true); if (!isNaN(a)) { - m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a; + m.value = smoothValue(m.value, a, m.smoothing); propsToSet.push({ id: layerID, title: propTitle, @@ -1133,7 +1181,7 @@ const Audio = function(tp, record) { case 'clarity': { const a = mapValue(m.c, 0.01, 0.05, m.min_out, m.max_out, true); if (!isNaN(a)) { - m.value = m.value * m.smoothing + (1.0 - m.smoothing) * a; + m.value = smoothValue(m.value, a, m.smoothing); propsToSet.push({ id: layerID, title: propTitle, @@ -1172,7 +1220,7 @@ const Audio = function(tp, record) { }; }); Object.keys(values).forEach((layerID) => { - deFlattenObject(values[layerID]); + deFlattenObject(values[layerID], ['color']); record.liveUpdater.immediateUpdate(getLayer(layerID), values[layerID]); }); //} @@ -1218,7 +1266,7 @@ const Audio = function(tp, record) { //} }); Object.keys(values).forEach((layerID) => { - deFlattenObject(values[layerID]); + deFlattenObject(values[layerID], ['color']); record.liveUpdater.immediateUpdate(getLayer(layerID), values[layerID]); }); } diff --git a/bin/em/variabletime/web/js/config.js b/bin/em/variabletime/web/js/config.js index ec0879f..143b720 100644 --- a/bin/em/variabletime/web/js/config.js +++ b/bin/em/variabletime/web/js/config.js @@ -91,7 +91,7 @@ const config = { 'rotation': [0, 180], 'mirror_x_distance': [0, 200], 'mirror_y_distance': [0, 70], - 'color': [0, 1], + 'color': [{'r': 0, 'g': 0, 'b': 0, 'a': 1}, {'r': 1, 'g': 1, 'b': 1, 'a': 1}], 'letterDelays': [0, 1000], }, ignoreProps: { @@ -109,7 +109,7 @@ const config = { fftBandsAnalysed: 256 * 8, fftBandsUsed: 256 / 2, fftHeight: 256 / 4, - colorSeparateRGBA: true, + colorSeparateRGBA: false, ignoreOutboundFrequencies: true, pitchCombineFrequencies: false, rolloverResetLoop: true, diff --git a/bin/em/variabletime/web/js/theatre-play.js b/bin/em/variabletime/web/js/theatre-play.js index 12f3d67..082fa86 100644 --- a/bin/em/variabletime/web/js/theatre-play.js +++ b/bin/em/variabletime/web/js/theatre-play.js @@ -346,6 +346,7 @@ const TheatrePlay = function(autoInit = false) { }; this.addShadowCss = () => { if (this.shadowRoot.querySelector(`#tpShadowCss`) === null) { + this.shadowRoot.insertBefore(Picker.StyleElement.cloneNode(true), this.shadowRoot.querySelector('#pointer-root')); let style = document.createElement("link"); style.setAttribute('id', 'tpShadowCss'); style.setAttribute('rel', 'stylesheet'); diff --git a/bin/em/variabletime/web/js/utils.js b/bin/em/variabletime/web/js/utils.js index f9f3424..2816a47 100644 --- a/bin/em/variabletime/web/js/utils.js +++ b/bin/em/variabletime/web/js/utils.js @@ -374,11 +374,37 @@ function arraysEqual(a, b, sortingMatters = false) { return true; } +// NOTE: will break if input is not number or rgba const mapValue = (value, low1, high1, low2, high2, clamp=false) => { - const mapped = low2 + (high2 - low2) * (value - low1) / (high1 - low1); - return clamp ? Math.min(high2 > low2 ? high2 : low2, Math.max(low2 < high2 ? low2 : high2, mapped)) : mapped; + if (typeof low2 === 'number') { + const mapped = low2 + (high2 - low2) * (value - low1) / (high1 - low1); + return clamp ? Math.min(high2 > low2 ? high2 : low2, Math.max(low2 < high2 ? low2 : high2, mapped)) : mapped; + } else if (typeof low2 === 'object' && typeof low2.r === 'number') { + const mapped = { + r: mapValue(value, low1, high1, low2.r, high2.r, clamp), + g: mapValue(value, low1, high1, low2.g, high2.g, clamp), + b: mapValue(value, low1, high1, low2.b, high2.b, clamp), + a: mapValue(value, low1, high1, low2.a, high2.a, clamp), + }; + return mapped; + } + return false; } +// NOTE: will break if input is not number or rgba +const smoothValue = (oldValue, newValue, smoothing) => { + if (typeof oldValue === 'number') { + return oldValue * smoothing + (1.0 - smoothing) * newValue; + } else { + return { + r: smoothValue(oldValue.r, newValue.r, smoothing), + g: smoothValue(oldValue.g, newValue.g, smoothing), + b: smoothValue(oldValue.b, newValue.b, smoothing), + a: smoothValue(oldValue.a, newValue.a, smoothing), + }; + } +}; + const isMobile = () => { if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { return true; @@ -478,6 +504,28 @@ const getNestedProperty = (o, a, verify = false) => { return o[b[0]]; }; +// NOTE: all input values are range 0-1 +const rgbaToHexa = (rgba) => { + return '#' + ( + ('0' + Math.round(rgba.r * 255).toString(16)).slice(-2) + + ('0' + Math.round(rgba.g * 255).toString(16)).slice(-2) + + ('0' + Math.round(rgba.b * 255).toString(16)).slice(-2) + + ('0' + Math.round(rgba.a * 255).toString(16)).slice(-2) + ).toUpperCase(); +}; + +// NOTE: all output values are range 0-1 +const hexaToRgba = (hexa) => { + const o = hexa[0] === '#' ? 1 : 0; + return { + r: parseInt(hexa.slice(o + 0, o + 2), 16) / 255, + g: parseInt(hexa.slice(o + 2, o + 4), 16) / 255, + b: parseInt(hexa.slice(o + 4, o + 6), 16) / 255, + a: parseInt(hexa.slice(o + 6, o + 8), 16) / 255 + } +}; + + ///////////////////////////////////// // you can test these functions in // the browser like so: @@ -507,6 +555,7 @@ export { getParents, arraysEqual, mapValue, + smoothValue, isMobile, sequencialPromises, toCssClass, @@ -514,4 +563,6 @@ export { flattenObject, deFlattenObject, getNestedProperty, + rgbaToHexa, + hexaToRgba, } diff --git a/bin/em/variabletime/web/js/vanilla-picker.js b/bin/em/variabletime/web/js/vanilla-picker.js new file mode 100644 index 0000000..e0a26d8 --- /dev/null +++ b/bin/em/variabletime/web/js/vanilla-picker.js @@ -0,0 +1,1009 @@ +/*! + * vanilla-picker v2.12.3 + * https://vanilla-picker.js.org + * + * Copyright 2017-2024 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate) + * Released under the ISC license. + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Picker = factory()); +})(this, (function () { 'use strict'; + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + var slicedToArray = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; + }(); + + String.prototype.startsWith = String.prototype.startsWith || function (needle) { + return this.indexOf(needle) === 0; + }; + String.prototype.padStart = String.prototype.padStart || function (len, pad) { + var str = this;while (str.length < len) { + str = pad + str; + }return str; + }; + + var colorNames = { cb: '0f8ff', tqw: 'aebd7', q: '-ffff', qmrn: '7fffd4', zr: '0ffff', bg: '5f5dc', bsq: 'e4c4', bck: '---', nch: 'ebcd', b: '--ff', bvt: '8a2be2', brwn: 'a52a2a', brw: 'deb887', ctb: '5f9ea0', hrt: '7fff-', chcT: 'd2691e', cr: '7f50', rnw: '6495ed', crns: '8dc', crms: 'dc143c', cn: '-ffff', Db: '--8b', Dcn: '-8b8b', Dgnr: 'b8860b', Dgr: 'a9a9a9', Dgrn: '-64-', Dkhk: 'bdb76b', Dmgn: '8b-8b', Dvgr: '556b2f', Drng: '8c-', Drch: '9932cc', Dr: '8b--', Dsmn: 'e9967a', Dsgr: '8fbc8f', DsTb: '483d8b', DsTg: '2f4f4f', Dtrq: '-ced1', Dvt: '94-d3', ppnk: '1493', pskb: '-bfff', mgr: '696969', grb: '1e90ff', rbrc: 'b22222', rwht: 'af0', stg: '228b22', chs: '-ff', gnsb: 'dcdcdc', st: '8f8ff', g: 'd7-', gnr: 'daa520', gr: '808080', grn: '-8-0', grnw: 'adff2f', hnw: '0fff0', htpn: '69b4', nnr: 'cd5c5c', ng: '4b-82', vr: '0', khk: '0e68c', vnr: 'e6e6fa', nrb: '0f5', wngr: '7cfc-', mnch: 'acd', Lb: 'add8e6', Lcr: '08080', Lcn: 'e0ffff', Lgnr: 'afad2', Lgr: 'd3d3d3', Lgrn: '90ee90', Lpnk: 'b6c1', Lsmn: 'a07a', Lsgr: '20b2aa', Lskb: '87cefa', LsTg: '778899', Lstb: 'b0c4de', Lw: 'e0', m: '-ff-', mgrn: '32cd32', nn: 'af0e6', mgnt: '-ff', mrn: '8--0', mqm: '66cdaa', mmb: '--cd', mmrc: 'ba55d3', mmpr: '9370db', msg: '3cb371', mmsT: '7b68ee', '': '-fa9a', mtr: '48d1cc', mmvt: 'c71585', mnLb: '191970', ntc: '5fffa', mstr: 'e4e1', mccs: 'e4b5', vjw: 'dead', nv: '--80', c: 'df5e6', v: '808-0', vrb: '6b8e23', rng: 'a5-', rngr: '45-', rch: 'da70d6', pgnr: 'eee8aa', pgrn: '98fb98', ptrq: 'afeeee', pvtr: 'db7093', ppwh: 'efd5', pchp: 'dab9', pr: 'cd853f', pnk: 'c0cb', pm: 'dda0dd', pwrb: 'b0e0e6', prp: '8-080', cc: '663399', r: '--', sbr: 'bc8f8f', rb: '4169e1', sbrw: '8b4513', smn: 'a8072', nbr: '4a460', sgrn: '2e8b57', ssh: '5ee', snn: 'a0522d', svr: 'c0c0c0', skb: '87ceeb', sTb: '6a5acd', sTgr: '708090', snw: 'afa', n: '-ff7f', stb: '4682b4', tn: 'd2b48c', t: '-8080', thst: 'd8bfd8', tmT: '6347', trqs: '40e0d0', vt: 'ee82ee', whT: '5deb3', wht: '', hts: '5f5f5', w: '-', wgrn: '9acd32' }; + + function printNum(num) { + var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\.$/, '') : num.toString(); + return str || '0'; + } + + var Color = function () { + function Color(r, g, b, a) { + classCallCheck(this, Color); + + + var that = this; + function parseString(input) { + + if (input.startsWith('hsl')) { + var _input$match$map = input.match(/([\-\d\.e]+)/g).map(Number), + _input$match$map2 = slicedToArray(_input$match$map, 4), + h = _input$match$map2[0], + s = _input$match$map2[1], + l = _input$match$map2[2], + _a = _input$match$map2[3]; + + if (_a === undefined) { + _a = 1; + } + + h /= 360; + s /= 100; + l /= 100; + that.hsla = [h, s, l, _a]; + } else if (input.startsWith('rgb')) { + var _input$match$map3 = input.match(/([\-\d\.e]+)/g).map(Number), + _input$match$map4 = slicedToArray(_input$match$map3, 4), + _r = _input$match$map4[0], + _g = _input$match$map4[1], + _b = _input$match$map4[2], + _a2 = _input$match$map4[3]; + + if (_a2 === undefined) { + _a2 = 1; + } + + that.rgba = [_r, _g, _b, _a2]; + } else { + if (input.startsWith('#')) { + that.rgba = Color.hexToRgb(input); + } else { + that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input); + } + } + } + + if (r === undefined) ; else if (Array.isArray(r)) { + this.rgba = r; + } else if (b === undefined) { + var color = r && '' + r; + if (color) { + parseString(color.toLowerCase()); + } + } else { + this.rgba = [r, g, b, a === undefined ? 1 : a]; + } + } + + createClass(Color, [{ + key: 'printRGB', + value: function printRGB(alpha) { + var rgb = alpha ? this.rgba : this.rgba.slice(0, 3), + vals = rgb.map(function (x, i) { + return printNum(x, i === 3 ? 3 : 0); + }); + + return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')'; + } + }, { + key: 'printHSL', + value: function printHSL(alpha) { + var mults = [360, 100, 100, 1], + suff = ['', '%', '%', '']; + + var hsl = alpha ? this.hsla : this.hsla.slice(0, 3), + vals = hsl.map(function (x, i) { + return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i]; + }); + + return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')'; + } + }, { + key: 'printHex', + value: function printHex(alpha) { + var hex = this.hex; + return alpha ? hex : hex.substring(0, 7); + } + }, { + key: 'rgba', + get: function get() { + if (this._rgba) { + return this._rgba; + } + if (!this._hsla) { + throw new Error('No color is set'); + } + + return this._rgba = Color.hslToRgb(this._hsla); + }, + set: function set(rgb) { + if (rgb.length === 3) { + rgb[3] = 1; + } + + this._rgba = rgb; + this._hsla = null; + } + }, { + key: 'rgbString', + get: function get() { + return this.printRGB(); + } + }, { + key: 'rgbaString', + get: function get() { + return this.printRGB(true); + } + }, { + key: 'hsla', + get: function get() { + if (this._hsla) { + return this._hsla; + } + if (!this._rgba) { + throw new Error('No color is set'); + } + + return this._hsla = Color.rgbToHsl(this._rgba); + }, + set: function set(hsl) { + if (hsl.length === 3) { + hsl[3] = 1; + } + + this._hsla = hsl; + this._rgba = null; + } + }, { + key: 'hslString', + get: function get() { + return this.printHSL(); + } + }, { + key: 'hslaString', + get: function get() { + return this.printHSL(true); + } + }, { + key: 'hex', + get: function get() { + var rgb = this.rgba, + hex = rgb.map(function (x, i) { + return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16); + }); + + return '#' + hex.map(function (x) { + return x.padStart(2, '0'); + }).join(''); + }, + set: function set(hex) { + this.rgba = Color.hexToRgb(hex); + } + }], [{ + key: 'hexToRgb', + value: function hexToRgb(input) { + + var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\w{3})$/, '$1F').replace(/^(\w)(\w)(\w)(\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\w{6})$/, '$1FF'); + + if (!hex.match(/^([0-9a-fA-F]{8})$/)) { + throw new Error('Unknown hex color; ' + input); + } + + var rgba = hex.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function (x) { + return parseInt(x, 16); + }); + + rgba[3] = rgba[3] / 255; + return rgba; + } + }, { + key: 'nameToRgb', + value: function nameToRgb(input) { + + var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4), + hex = colorNames[hash]; + return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\-/g, '00').padStart(6, 'f')); + } + }, { + key: 'rgbToHsl', + value: function rgbToHsl(_ref) { + var _ref2 = slicedToArray(_ref, 4), + r = _ref2[0], + g = _ref2[1], + b = _ref2[2], + a = _ref2[3]; + + r /= 255; + g /= 255; + b /= 255; + + var max = Math.max(r, g, b), + min = Math.min(r, g, b); + var h = void 0, + s = void 0, + l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0);break; + case g: + h = (b - r) / d + 2;break; + case b: + h = (r - g) / d + 4;break; + } + + h /= 6; + } + + return [h, s, l, a]; + } + }, { + key: 'hslToRgb', + value: function hslToRgb(_ref3) { + var _ref4 = slicedToArray(_ref3, 4), + h = _ref4[0], + s = _ref4[1], + l = _ref4[2], + a = _ref4[3]; + + var r = void 0, + g = void 0, + b = void 0; + + if (s === 0) { + r = g = b = l; + } 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, + p = 2 * l - q; + + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + var rgba = [r * 255, g * 255, b * 255].map(Math.round); + rgba[3] = a; + + return rgba; + } + }]); + return Color; + }(); + + var EventBucket = function () { + function EventBucket() { + classCallCheck(this, EventBucket); + + this._events = []; + } + + createClass(EventBucket, [{ + key: 'add', + value: function add(target, type, handler) { + target.addEventListener(type, handler, false); + this._events.push({ + target: target, + type: type, + handler: handler + }); + } + }, { + key: 'remove', + value: function remove(target, type, handler) { + this._events = this._events.filter(function (e) { + var isMatch = true; + if (target && target !== e.target) { + isMatch = false; + } + if (type && type !== e.type) { + isMatch = false; + } + if (handler && handler !== e.handler) { + isMatch = false; + } + + if (isMatch) { + EventBucket._doRemove(e.target, e.type, e.handler); + } + return !isMatch; + }); + } + }, { + key: 'destroy', + value: function destroy() { + this._events.forEach(function (e) { + return EventBucket._doRemove(e.target, e.type, e.handler); + }); + this._events = []; + } + }], [{ + key: '_doRemove', + value: function _doRemove(target, type, handler) { + target.removeEventListener(type, handler, false); + } + }]); + return EventBucket; + }(); + + function parseHTML(htmlString) { + + var div = document.createElement('div'); + div.innerHTML = htmlString; + return div.firstElementChild; + } + + function dragTrack(eventBucket, area, callback) { + var dragging = false; + + function clamp(val, min, max) { + return Math.max(min, Math.min(val, max)); + } + + function onMove(e, info, starting) { + if (starting) { + dragging = true; + } + if (!dragging) { + return; + } + + e.preventDefault(); + + var bounds = area.getBoundingClientRect(), + w = bounds.width, + h = bounds.height, + x = info.clientX, + y = info.clientY; + + var relX = clamp(x - bounds.left, 0, w), + relY = clamp(y - bounds.top, 0, h); + + callback(relX / w, relY / h); + } + + function onMouse(e, starting) { + var button = e.buttons === undefined ? e.which : e.buttons; + if (button === 1) { + onMove(e, e, starting); + } else { + dragging = false; + } + } + + function onTouch(e, starting) { + if (e.touches.length === 1) { + onMove(e, e.touches[0], starting); + } else { + dragging = false; + } + } + + eventBucket.add(area, 'mousedown', function (e) { + onMouse(e, true); + }); + eventBucket.add(area, 'touchstart', function (e) { + onTouch(e, true); + }); + eventBucket.add(window, 'mousemove', onMouse); + eventBucket.add(area, 'touchmove', onTouch); + eventBucket.add(window, 'mouseup', function (e) { + dragging = false; + }); + eventBucket.add(area, 'touchend', function (e) { + dragging = false; + }); + eventBucket.add(area, 'touchcancel', function (e) { + dragging = false; + }); + } + + var BG_TRANSP = 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em'; + var HUES = 360; + + var EVENT_KEY = 'keydown', + EVENT_CLICK_OUTSIDE = 'mousedown', + EVENT_TAB_MOVE = 'focusin'; + + function $(selector, context) { + return (context || document).querySelector(selector); + } + + function stopEvent(e) { + + e.preventDefault(); + e.stopPropagation(); + } + function onKey(bucket, target, keys, handler, stop) { + bucket.add(target, EVENT_KEY, function (e) { + if (keys.indexOf(e.key) >= 0) { + if (stop) { + stopEvent(e); + } + handler(e); + } + }); + } + + var Picker = function () { + function Picker(options) { + classCallCheck(this, Picker); + + + this.settings = { + + popup: 'right', + layout: 'default', + alpha: true, + editor: true, + editorFormat: 'hex', + cancelButton: false, + defaultColor: '#0cf' + }; + + this._events = new EventBucket(); + + this.onChange = null; + + this.onDone = null; + + this.onOpen = null; + + this.onClose = null; + + this.setOptions(options); + } + + createClass(Picker, [{ + key: 'setOptions', + value: function setOptions(options) { + var _this = this; + + if (!options) { + return; + } + var settings = this.settings; + + function transfer(source, target, skipKeys) { + for (var key in source) { + if (skipKeys && skipKeys.indexOf(key) >= 0) { + continue; + } + + target[key] = source[key]; + } + } + + if (options instanceof HTMLElement) { + settings.parent = options; + } else { + + if (settings.parent && options.parent && settings.parent !== options.parent) { + this._events.remove(settings.parent); + this._popupInited = false; + } + + transfer(options, settings); + + if (options.onChange) { + this.onChange = options.onChange; + } + if (options.onDone) { + this.onDone = options.onDone; + } + if (options.onOpen) { + this.onOpen = options.onOpen; + } + if (options.onClose) { + this.onClose = options.onClose; + } + + var col = options.color || options.colour; + if (col) { + this._setColor(col); + } + } + + var parent = settings.parent; + if (parent && settings.popup && !this._popupInited) { + + var openProxy = function openProxy(e) { + return _this.openHandler(e); + }; + + this._events.add(parent, 'click', openProxy); + + onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy); + + this._popupInited = true; + } else if (options.parent && !settings.popup) { + this.show(); + } + } + }, { + key: 'openHandler', + value: function openHandler(e) { + if (this.show()) { + + e && e.preventDefault(); + + this.settings.parent.style.pointerEvents = 'none'; + + var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement; + setTimeout(function () { + return toFocus.focus(); + }, 100); + + if (this.onOpen) { + this.onOpen(this.colour); + } + } + } + }, { + key: 'closeHandler', + value: function closeHandler(e) { + var event = e && e.type; + var doHide = false; + + if (!e) { + doHide = true; + } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) { + + var knownTime = (this.__containedEvent || 0) + 100; + if (e.timeStamp > knownTime) { + doHide = true; + } + } else { + + stopEvent(e); + + doHide = true; + } + + if (doHide && this.hide()) { + this.settings.parent.style.pointerEvents = ''; + + if (event !== EVENT_CLICK_OUTSIDE) { + this.settings.parent.focus(); + } + + if (this.onClose) { + this.onClose(this.colour); + } + } + } + }, { + key: 'movePopup', + value: function movePopup(options, open) { + + this.closeHandler(); + + this.setOptions(options); + if (open) { + this.openHandler(); + } + } + }, { + key: 'setColor', + value: function setColor(color, silent) { + this._setColor(color, { silent: silent }); + } + }, { + key: '_setColor', + value: function _setColor(color, flags) { + if (typeof color === 'string') { + color = color.trim(); + } + if (!color) { + return; + } + + flags = flags || {}; + var c = void 0; + try { + + c = new Color(color); + } catch (ex) { + if (flags.failSilently) { + return; + } + throw ex; + } + + if (!this.settings.alpha) { + var hsla = c.hsla; + hsla[3] = 1; + c.hsla = hsla; + } + this.colour = this.color = c; + this._setHSLA(null, null, null, null, flags); + } + }, { + key: 'setColour', + value: function setColour(colour, silent) { + this.setColor(colour, silent); + } + }, { + key: 'show', + value: function show() { + var parent = this.settings.parent; + if (!parent) { + return false; + } + + if (this.domElement) { + var toggled = this._toggleDOM(true); + + this._setPosition(); + + return toggled; + } + + var html = this.settings.template || '
'; + var wrapper = parseHTML(html); + + this.domElement = wrapper; + this._domH = $('.picker_hue', wrapper); + this._domSL = $('.picker_sl', wrapper); + this._domA = $('.picker_alpha', wrapper); + this._domEdit = $('.picker_editor input', wrapper); + this._domSample = $('.picker_sample', wrapper); + this._domOkay = $('.picker_done button', wrapper); + this._domCancel = $('.picker_cancel button', wrapper); + + wrapper.classList.add('layout_' + this.settings.layout); + if (!this.settings.alpha) { + wrapper.classList.add('no_alpha'); + } + if (!this.settings.editor) { + wrapper.classList.add('no_editor'); + } + if (!this.settings.cancelButton) { + wrapper.classList.add('no_cancel'); + } + this._ifPopup(function () { + return wrapper.classList.add('popup'); + }); + + this._setPosition(); + + if (this.colour) { + this._updateUI(); + } else { + this._setColor(this.settings.defaultColor); + } + this._bindEvents(); + + return true; + } + }, { + key: 'hide', + value: function hide() { + return this._toggleDOM(false); + } + }, { + key: 'destroy', + value: function destroy() { + this._events.destroy(); + if (this.domElement) { + this.settings.parent.removeChild(this.domElement); + } + } + }, { + key: '_bindEvents', + value: function _bindEvents() { + var _this2 = this; + + var that = this, + dom = this.domElement, + events = this._events; + + function addEvent(target, type, handler) { + events.add(target, type, handler); + } + + addEvent(dom, 'click', function (e) { + return e.preventDefault(); + }); + + dragTrack(events, this._domH, function (x, y) { + return that._setHSLA(x); + }); + + dragTrack(events, this._domSL, function (x, y) { + return that._setHSLA(null, x, 1 - y); + }); + + if (this.settings.alpha) { + dragTrack(events, this._domA, function (x, y) { + return that._setHSLA(null, null, null, 1 - y); + }); + } + + var editInput = this._domEdit; + { + addEvent(editInput, 'input', function (e) { + that._setColor(this.value, { fromEditor: true, failSilently: true }); + }); + + addEvent(editInput, 'focus', function (e) { + var input = this; + + if (input.selectionStart === input.selectionEnd) { + input.select(); + } + }); + } + + this._ifPopup(function () { + + var popupCloseProxy = function popupCloseProxy(e) { + return _this2.closeHandler(e); + }; + + addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy); + addEvent(window, EVENT_TAB_MOVE, popupCloseProxy); + onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy); + + var timeKeeper = function timeKeeper(e) { + _this2.__containedEvent = e.timeStamp; + }; + addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper); + + addEvent(dom, EVENT_TAB_MOVE, timeKeeper); + + addEvent(_this2._domCancel, 'click', popupCloseProxy); + }); + + var onDoneProxy = function onDoneProxy(e) { + _this2._ifPopup(function () { + return _this2.closeHandler(e); + }); + if (_this2.onDone) { + _this2.onDone(_this2.colour); + } + }; + addEvent(this._domOkay, 'click', onDoneProxy); + onKey(events, dom, ['Enter'], onDoneProxy); + } + }, { + key: '_setPosition', + value: function _setPosition() { + var parent = this.settings.parent, + elm = this.domElement; + + if (parent !== elm.parentNode) { + parent.appendChild(elm); + } + + this._ifPopup(function (popup) { + + if (getComputedStyle(parent).position === 'static') { + parent.style.position = 'relative'; + } + + var cssClass = popup === true ? 'popup_right' : 'popup_' + popup; + + ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) { + + if (c === cssClass) { + elm.classList.add(c); + } else { + elm.classList.remove(c); + } + }); + + elm.classList.add(cssClass); + }); + } + }, { + key: '_setHSLA', + value: function _setHSLA(h, s, l, a, flags) { + flags = flags || {}; + + var col = this.colour, + hsla = col.hsla; + + [h, s, l, a].forEach(function (x, i) { + if (x || x === 0) { + hsla[i] = x; + } + }); + col.hsla = hsla; + + this._updateUI(flags); + + if (this.onChange && !flags.silent) { + this.onChange(col); + } + } + }, { + key: '_updateUI', + value: function _updateUI(flags) { + if (!this.domElement) { + return; + } + flags = flags || {}; + + var col = this.colour, + hsl = col.hsla, + cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)', + cssHSL = col.hslString, + cssHSLA = col.hslaString; + + var uiH = this._domH, + uiSL = this._domSL, + uiA = this._domA, + thumbH = $('.picker_selector', uiH), + thumbSL = $('.picker_selector', uiSL), + thumbA = $('.picker_selector', uiA); + + function posX(parent, child, relX) { + child.style.left = relX * 100 + '%'; + } + function posY(parent, child, relY) { + child.style.top = relY * 100 + '%'; + } + + posX(uiH, thumbH, hsl[0]); + + this._domSL.style.backgroundColor = this._domH.style.color = cssHue; + + posX(uiSL, thumbSL, hsl[1]); + posY(uiSL, thumbSL, 1 - hsl[2]); + + uiSL.style.color = cssHSL; + + posY(uiA, thumbA, 1 - hsl[3]); + + var opaque = cssHSL, + transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'), + bg = 'linear-gradient(' + [opaque, transp] + ')'; + + this._domA.style.background = bg + ', ' + BG_TRANSP; + + if (!flags.fromEditor) { + var format = this.settings.editorFormat, + alpha = this.settings.alpha; + + var value = void 0; + switch (format) { + case 'rgb': + value = col.printRGB(alpha);break; + case 'hsl': + value = col.printHSL(alpha);break; + default: + value = col.printHex(alpha); + } + this._domEdit.value = value; + } + + this._domSample.style.color = cssHSLA; + } + }, { + key: '_ifPopup', + value: function _ifPopup(actionIf, actionElse) { + if (this.settings.parent && this.settings.popup) { + actionIf && actionIf(this.settings.popup); + } else { + actionElse && actionElse(); + } + } + }, { + key: '_toggleDOM', + value: function _toggleDOM(toVisible) { + var dom = this.domElement; + if (!dom) { + return false; + } + + var displayStyle = toVisible ? '' : 'none', + toggle = dom.style.display !== displayStyle; + + if (toggle) { + dom.style.display = displayStyle; + } + return toggle; + } + }]); + return Picker; + }(); + + { + var style = document.createElement('style'); + style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}'; + document.documentElement.firstElementChild.appendChild(style); + + Picker.StyleElement = style; + } + + return Picker; + +})); diff --git a/browser.sh b/browser.sh index 533746c..002fb2d 100755 --- a/browser.sh +++ b/browser.sh @@ -9,11 +9,14 @@ fly () DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" PREVIOUS_DIR=$(pwd) +#. ~/.bash_aliases + cd $DIR #echo $(fly /usr/bin/chromium --incognito --screen=1 $@) #/usr/bin/chromium --incognito --screen=1 $@ & fly flatpak run com.github.Eloston.UngoogledChromium --screen=1 --disk-cache-dir=/dev/null --disk-cache-size=1 --enable-logging --password-store=basic --v=1 $@ & +#flatchrome Tmp --screen=1 --disk-cache-dir=/dev/null --disk-cache-size=1 --enable-logging --password-store=basic --v=1 $@ & browser_pid=$! echo $browser_pid > .browserpid