changeset 1610:b0846845c772

colorpick: new gradients. use one.color lib. value slider. Ignore-this: 71dbe8eb434de6660bc6f7a1dc0bad6e
author Drew Perttula <drewp@bigasterisk.com>
date Mon, 05 Jun 2017 09:38:08 +0000
parents 0bb3051fd6fd
children 826e295b6a75
files light9/web/colorpick_rainbow_large.png light9/web/colorpick_rainbow_small.png light9/web/lib/bower.json light9/web/light9-color-picker.html light9/web/live/index.html light9/web/live/live.coffee
diffstat 6 files changed, 75 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
Binary file light9/web/colorpick_rainbow_large.png has changed
Binary file light9/web/colorpick_rainbow_small.png has changed
--- a/light9/web/lib/bower.json	Mon Jun 05 08:28:50 2017 +0000
+++ b/light9/web/lib/bower.json	Mon Jun 05 09:38:08 2017 +0000
@@ -20,7 +20,8 @@
     "paper-radio-button": "PolymerElements/paper-radio-button#^1.2.2",
     "paper-button": "PolymerElements/paper-button#^1.0.12",
     "paper-dialog": "PolymerElements/paper-dialog#^1.0.4",
-    "paper-radio-group": "PolymerElements/paper-radio-group#^1.2.2"
+    "paper-radio-group": "PolymerElements/paper-radio-group#^1.2.2",
+    "color": "https://github.com/One-com/one-color.git#^3.0.4"
   },
   "resolutions": {
     "paper-styles": "^1.1.4",
--- a/light9/web/light9-color-picker.html	Mon Jun 05 08:28:50 2017 +0000
+++ b/light9/web/light9-color-picker.html	Mon Jun 05 09:38:08 2017 +0000
@@ -5,6 +5,8 @@
     <style>
      :host {
          position: relative;
+         display: flex;
+         align-items: center;
      }
      #smallRainbowComp, #largeRainbowComp {
          display: inline-block;
@@ -39,6 +41,9 @@
          width: 1000px; 
          height: 1000px;
      }
+     #smallRainbowComp {
+         margin-right: 3px;
+     }
      #largeRainbowComp {
          display: none;
          position: absolute;
@@ -53,6 +58,12 @@
       <div id="smallRainbow" on-mouseenter="onEnterSmall"></div>
       <div id="smallCrosshair"></div>
     </div>
+    <span>V:</span>
+    <paper-slider min="0"
+                  max="255"
+                  step="1"
+                  value="{{sliderWriteValue}}"
+                  immediate-value="{{value}}"></paper-slider>
     <div id="largeRainbowComp">
       <div id="largeRainbow"
            on-mousemove="onCanvasMove"
@@ -61,6 +72,7 @@
       <div id="largeCrosshair"></div>
     </div>
   </template>
+  <script src="/lib/color/one-color.js"></script>
   <script>
    class RainbowCanvas {
        constructor(url, size) {
@@ -86,38 +98,26 @@
            for (var y = 0; y < this.size[1]; y+=1) {
                for (var x = 0; x < this.size[0]; x+=1) {
                    var base = (y * this.size[0] + x) * 4;
-                   var c = this._hexFromRgb(
-                       data[base + 0], data[base + 1], data[base + 2]);
+                   var c = one.color([data[base + 0],
+                                      data[base + 1],
+                                      data[base + 2], 255]).hex();
                    this.colorPos[c] = [x, y];
                }
            }
-       }
-       _hexFromRgb(r, g, b) {
-           var hex = function (x) {
-               return ('00' + x.toString(16)).slice(-2);
-           };
-           return '#' + hex(r) + hex(g) + hex(b);
-       }
+       }       
        colorAt(pos) {
            var data = this.ctx.getImageData(pos[0], pos[1], 1, 1).data;
-           return this._hexFromRgb(data[0], data[1], data[2]);
-       }
-       _fullBrightness(r, g, b) {
-           var high = Math.max(r, g, b);
-           if (high == 0) {
-               return [0, 0, 0];
-           }
-           return [Math.floor(255 * r / high),
-                   Math.floor(255 * g / high),
-                   Math.floor(255 * b / high)];
+           return one.color([data[0], data[1], data[2], 255]).hex();
        }
        posFor(color) {
-           let r = parseInt(color.substr(1, 2), 16),
-               g = parseInt(color.substr(3, 2), 16),
-               b = parseInt(color.substr(5, 2), 16);
-
-           let bright = this._fullBrightness(r, g, b);
-           r = bright[0]; g = bright[1]; b = bright[2];
+           if (color == '#000000') {
+               throw new Error('no match');
+           }
+           
+           let bright = one.color(color).value(1).hex();
+           let r = parseInt(bright.substr(1, 2), 16),
+               g = parseInt(bright.substr(3, 2), 16),
+               b = parseInt(bright.substr(5, 2), 16);
            
            // We may not have a match for this color exactly (e.g. on
            // the small image), so we have to search for a near one.
@@ -131,7 +131,7 @@
                    for (var db = 0; db < radius; db = walk(db)) {
                        // Don't need bounds check- out of range
                        // corrupt colors just won't match.
-                       color = this._hexFromRgb(r + dr, g + dg, b + db);
+                       color = one.color([r + dr, g + dg, b + db, 255]).hex();
                        var pos = this.colorPos[color];
                        if (pos !== undefined) {
                            return pos;
@@ -146,9 +146,19 @@
    Polymer({
        is: "light9-color-picker",
        properties: {
-           value: { type: String, notify: true },
+           color: {
+               type: String,
+               notify: true,
+           },
+           hueSatColor: { type: String, notify: true, value: '#000000' },
+           value: { type: Number, notify: true }, // 0..255
+           sliderWriteValue: { type: Number, notify: true },
        },
-       observers: ['updateSmall(value)'],
+       observers: [
+           'updateSmall(color)',
+           'onValue(value)',
+           'writeColor(hueSatColor, value)'
+       ],
        attached: function() {
            if (!window.pickerCanvases) {
                window.pickerCanvases = {
@@ -161,9 +171,19 @@
            this.large = window.pickerCanvases.large;
            this.small = window.pickerCanvases.small;
        },
-       updateSmall: function(value) {
+       onValue: function(value) {
+           let neverBlack = .1 + .9 * value / 255;
+           this.$.smallRainbow.style.filter = `brightness(${neverBlack})`;
+       },
+       writeColor: function(hueSatColor, value) {
+           this.color = one.color(hueSatColor).value(value / 255).hex();
+       },
+       updateSmall: function(color) {
+           // setting immediate-value doesn't work
+           this.sliderWriteValue = one.color(color).value() * 255;
+           
            try {
-               var pos = this.small.posFor(value);
+               var pos = this.small.posFor(color);
            } catch(e) {
                this.moveSmallCrosshair([-999, -999]);
                return;
@@ -185,7 +205,7 @@
            this._floatLarge();
            this.$.largeRainbowComp.style.display = 'block';
            try {
-               this.moveLargeCrosshair(this.large.posFor(this.value));
+               this.moveLargeCrosshair(this.large.posFor(this.color));
            } catch(e) {
                this.moveLargeCrosshair([-999, -999]);
                return;
@@ -214,7 +234,12 @@
            var pos = [ev.offsetX - canvas.offsetLeft,
                       ev.offsetY - canvas.offsetTop];
            this.moveLargeCrosshair(pos);
-           this.value = this.large.colorAt(pos);
+           this.hueSatColor = this.large.colorAt(pos);
+
+           // special case: it's useless to adjust the hue/sat of black
+           if (this.value == 0) {
+               this.value = 255;
+           }
        },
    });
   </script>
--- a/light9/web/live/index.html	Mon Jun 05 08:28:50 2017 +0000
+++ b/light9/web/live/index.html	Mon Jun 05 09:38:08 2017 +0000
@@ -23,7 +23,17 @@
     <dom-module id="light9-live-control">
       <template>
         <style>
-         paper-slider { width: 100%; margin: -19px 0; }
+         #colorControls {
+             display: flex;
+             align-items: center;
+         }
+         #colorControls > * {
+             margin: 0 3px;
+         }
+         #colorControls paper-slider {
+
+             }
+         paper-slider { width: 100%; height: 25px; }
         </style>
 
         <style is="custom-style">
@@ -49,13 +59,11 @@
                         immediate-value="{{immediateSlider}}"></paper-slider>
         </template>
         <template is="dom-if" if="{{deviceAttr.useColor}}">
-          <input type="color"
-                 id="col"
-                 on-input="onPickedColor"
-                 value="{{pickedColor}}">
-          <button on-click="goWhite">white</button>
-          <button on-click="goBlack">black</button>
-          <light9-color-picker value="{{value}}"></light9-color-picker>
+        <div id="colorControls">
+          <button on-click="goBlack">0.0</button>
+          <light9-color-picker color="{{value}}"></light9-color-picker>
+         
+        </div>
         </template>
         <template is="dom-if" if="{{deviceAttr.useChoice}}">
           <select size$="{{deviceAttr.choiceSize}}" value="{{pickedChoice::change}}">
--- a/light9/web/live/live.coffee	Mon Jun 05 08:28:50 2017 +0000
+++ b/light9/web/live/live.coffee	Mon Jun 05 09:38:08 2017 +0000
@@ -9,16 +9,13 @@
     value: { type: Object, notify: true }
     
     immediateSlider: { notify: true, observer: 'onSlider' }
-    pickedColor: { observer: 'onPickedColor' }
     pickedChoice: { observer: 'onChange' }
   observers: [
     'onChange(value)'
     ]
   ready: ->
     
-  onPickedColor: (ev) -> @value = ev.target.value
   onSlider: -> @value = @immediateSlider
-  goWhite: -> @value = "#ffffff"
   goBlack: -> @value = "#000000"
   onChange: (value) ->
     @lastSent = [[@device, @deviceAttr.uri, value]]