diff --git a/src/mami.css/colpick.css b/src/mami.css/colpick.css index 8223512..6f960b5 100644 --- a/src/mami.css/colpick.css +++ b/src/mami.css/colpick.css @@ -157,11 +157,13 @@ } .colpick-presets-option { display: block; + border: 0; width: 40px; height: 40px; border-radius: 5px; text-decoration: none; color: #fff; + cursor: pointer; } .colpick-presets-option:focus { box-shadow: 0 0 0 1px #fff, 0 0 0 2px #000, inset 0 0 0 1px #000; @@ -175,6 +177,8 @@ grid-template-columns: repeat(12, minmax(0, 1fr)); } .colpick-grid-option { + display: block; + border: 0; width: 23px; height: 23px; z-index: 1; diff --git a/src/mami.js/colour.js b/src/mami.js/colour.js new file mode 100644 index 0000000..fdc5284 --- /dev/null +++ b/src/mami.js/colour.js @@ -0,0 +1,69 @@ +const MamiColour = (() => { + const readThres = 168, + lumiRed = .299, + lumiGreen = .587, + lumiBlue = .114; + + const pub = {}; + + const extractRGB = raw => [ + (raw >> 16) & 0xFF, + (raw >> 8) & 0xFF, + raw & 0xFF, + ]; + + const luminance = raw => { + const rgb = extractRGB(raw); + return rgb[0] * lumiRed + + rgb[1] * lumiGreen + + rgb[2] * lumiBlue; + }; + + const weightedNumber = (num1, num2, weight) => { + weight = Math.min(1, Math.max(0, weight)); + return Math.round((num1 * weight) + (num2 * (1 - weight))); + }; + + const weighted = (raw1, raw2, weight) => { + const rgb1 = extractRGB(raw1), + rgb2 = extractRGB(raw2); + return (weightedNumber(rgb1[0], rgb2[0], weight) << 16) + | (weightedNumber(rgb1[1], rgb2[1], weight) << 8) + | weightedNumber(rgb1[2], rgb2[2], weight); + }; + + pub.extractRGB = extractRGB; + pub.weightedNumber = weightedNumber; + pub.luminance = luminance; + pub.weighted = weighted; + + pub.text = raw => luminance(raw) > readThres ? 0 : 0xFFFFFF; + + pub.shaded = (raw, offset) => { + if(offset == 0) + return raw; + + let dir = 0xFFFFFF; + if(offset < 0) { + dir = 0; + offset *= -1; + } + + return weighted(dir, raw, offset); + }; + + pub.hexByte = raw => { + let str = raw.toString(16).substring(0, 2); + return str.length < 2 + ? `0${str}` : str; + }; + + pub.hex = raw => { + let str = raw.toString(16).substring(0, 6); + if(str.length < 6) + str = '000000'.substring(str.length) + str; + return `#${str}`; + }; + + return pub; +})(); diff --git a/src/mami.js/colpick/picker.jsx b/src/mami.js/colpick/picker.jsx index a3730d5..193f42c 100644 --- a/src/mami.js/colpick/picker.jsx +++ b/src/mami.js/colpick/picker.jsx @@ -1,3 +1,8 @@ +#include colour.js +#include colpick/tgrid.jsx +#include colpick/tpresets.jsx +#include colpick/tsliders.jsx + const MamiColourPicker = function(callback, options, colour, onClose) { if(typeof callback !== 'function') return; @@ -6,59 +11,6 @@ const MamiColourPicker = function(callback, options, colour, onClose) { if(typeof colour !== 'number') colour = parseInt(colour || 0); - const readThres = 168, - lumiRed = .299, - lumiGreen = .587, - lumiBlue = .114; - - const hexFormat = raw => { - let str = raw.toString(16).substring(0, 6); - if(str.length < 6) - str = '000000'.substring(str.length) + str; - return `#${str}`; - }; - - const extractRGB = raw => [ - (raw >> 16) & 0xFF, - (raw >> 8) & 0xFF, - raw & 0xFF, - ]; - - const calcLumi = raw => { - const rgb = extractRGB(raw); - return rgb[0] * lumiRed - + rgb[1] * lumiGreen - + rgb[2] * lumiBlue; - }; - - const textColour = raw => calcLumi(raw) > readThres ? 0 : 0xFFFFFF; - - const weightNum = (n1, n2, w) => { - w = Math.min(1, Math.max(0, w)); - return Math.round((n1 * w) + (n2 * (1 - w))); - }; - - const weightColour = (c1, c2, w) => { - c1 = extractRGB(c1); - c2 = extractRGB(c2); - return (weightNum(c1[0], c2[0], w) << 16) - | (weightNum(c1[1], c2[1], w) << 8) - | weightNum(c1[2], c2[2], w); - }; - - const shadeColour = (raw, offset) => { - if(offset == 0) - return raw; - - let dir = 0xFFFFFF; - if(offset < 0) { - dir = 0; - offset *= -1; - } - - return weightColour(dir, raw, offset); - }; - const verifyOption = (name, type, def) => { if(typeof options[name] !== type) options[name] = def; @@ -76,34 +28,27 @@ const MamiColourPicker = function(callback, options, colour, onClose) { const onColourChange = []; const runOnColourChange = () => { - const text = textColour(colour); + const text = MamiColour.text(colour); for(const handler of onColourChange) handler(colour, text); }; - const setColour = raw => { - colour = parseInt(raw || 0) & 0xFFFFFF; + const setColour = (raw, mask) => { + raw = raw === undefined ? 0 : parseInt(raw); + mask = mask === undefined ? ~0 : parseInt(mask); + + colour = (colour & ~mask) | (raw & mask); runOnColourChange(); }; - const runCallback = apply => { - const result = Object.defineProperties({}, { - apply: { value: apply }, - colour: { value: colour }, - hex: { get() { return hexFormat(colour); } }, - }); - - callback(result); - }; - const apply = () => { - runCallback(true); + callback(colour); if(options.autoClose) close(); }; const cancel = () => { - runCallback(false); + callback(null); if(options.autoClose) close(); }; @@ -118,8 +63,8 @@ const MamiColourPicker = function(callback, options, colour, onClose) { const container =
; onColourChange.push((colour, text) => { - container.style.setProperty('--colpick-colour', hexFormat(colour)); - container.style.setProperty('--colpick-text', hexFormat(text)); + container.style.setProperty('--colpick-colour', MamiColour.hex(colour)); + container.style.setProperty('--colpick-text', MamiColour.hex(text)); }); const form =