changeset 1747:5c4d6be0f0fe

mostly fix color-picker Ignore-this: 69439cfab532bc39c097eef090cbfddb
author Drew Perttula <drewp@bigasterisk.com>
date Wed, 23 May 2018 09:53:07 +0000
parents 84adc69fdf8a
children 7ec3eec60ea4
files light9/web/light9-color-picker.html light9/web/timeline/inline-attrs.coffee
diffstat 2 files changed, 160 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/light9/web/light9-color-picker.html	Tue May 22 06:42:10 2018 +0000
+++ b/light9/web/light9-color-picker.html	Wed May 23 09:53:07 2018 +0000
@@ -1,6 +1,60 @@
 <link rel="import" href="/lib/polymer/polymer.html">
 <link rel="import" href="/lib/paper-slider/paper-slider.html">
 
+<dom-module id="light9-color-picker-float">
+  <template>
+    <style>
+     :host {
+         z-index: 10;
+         position: fixed;
+     }
+     #largeCrosshair {
+         position: absolute;
+         left: -60px;
+         top: -62px;
+         pointer-events: none;
+     }
+     #largeCrosshair {
+         background: url(/colorpick_crosshair_large.svg);
+         width: 1000px; 
+         height: 1000px;
+     }
+    #largeRainbowComp {
+         display: inline-block;
+         overflow: hidden;
+         position: relative;
+     }
+     #largeRainbowComp {
+         position: absolute;
+         border: 4px solid #545454;
+         box-shadow: 8px 11px 40px 0px rgba(0, 0, 0, 0.74);
+         left: 0x;
+         top: 0;
+     }
+     #largeRainbow {
+         background: url(/colorpick_rainbow_large.png);
+         width: 400px; 
+         height: 200px;
+         user-select: none;
+     }
+    </style>
+    <div id="largeRainbowComp">
+      <div id="largeRainbow"
+           on-mousemove="onCanvasMove"
+           on-mouseup="hideLarge"
+           on-mouseleave="hideLarge"></div>
+      <div id="largeCrosshair"></div>
+    </div>
+  </template>
+  <script>
+   class Light9ColorPickerFloat extends Polymer.Element {
+       static get is() { return "light9-color-picker-float"; }
+       // more methods get added by Light9ColorPicker
+   }
+   customElements.define(Light9ColorPickerFloat.is, Light9ColorPickerFloat);
+  </script>
+</dom-module>
+
 <dom-module id="light9-color-picker">
   <template>
     <style>
@@ -10,7 +64,7 @@
          align-items: center;
          flex-wrap: wrap;
      }
-     #smallRainbowComp, #largeRainbowComp {
+     #smallRainbowComp {
          display: inline-block;
          overflow: hidden;
          position: relative;
@@ -20,13 +74,8 @@
          width: 150px; 
          height: 30px;
      }
-     #largeRainbow {
-         background: url(/colorpick_rainbow_large.png);
-         width: 400px; 
-         height: 200px;
-         user-select: none;
-     }
-     #smallCrosshair, #largeCrosshair {
+     
+     #smallCrosshair {
          position: absolute;
          left: -60px;
          top: -62px;
@@ -39,23 +88,11 @@
          width: 400px; 
          height: 60px;
      }
-     #largeCrosshair {
-         background: url(/colorpick_crosshair_large.svg);
-         width: 1000px; 
-         height: 1000px;
-     }
+     
      #smallRainbowComp {
          margin-right: 3px;
      }
-     #largeRainbowComp {
-         display: none;
-         position: absolute;
-         border: 4px solid #545454;
-         box-shadow: 8px 11px 40px 0px rgba(0, 0, 0, 0.74);
-         z-index: 10;
-         left: -50px;
-         top: -110px;
-     }
+     
      paper-slider {
          width: 170px;
      }
@@ -63,26 +100,26 @@
          display: flex;
          align-items: center;
      }
-    </style>
-    <div id="smallRainbowComp">
-      <div id="smallRainbow" on-mouseenter="onEnterSmall"></div>
-      <div id="smallCrosshair"></div>
-    </div>
-    <span id="vee">
-      V:
-      <paper-slider min="0"
-                    max="255"
-                    step="1"
-                    value="{{sliderWriteValue}}"
-                    immediate-value="{{value}}"></paper-slider>
-    </span>
-    <div id="largeRainbowComp">
-      <div id="largeRainbow"
-           on-mousemove="onCanvasMove"
-           on-mouseup="hideLarge"
-           on-mouseleave="hideLarge"></div>
-      <div id="largeCrosshair"></div>
-    </div>
+     #large {
+         display: none;
+     }
+     </style>
+     <div id="smallRainbowComp">
+     <div id="smallRainbow" on-mouseenter="onEnterSmall"></div>
+     <div id="smallCrosshair"></div>
+     </div>
+     <span id="vee">
+     V:
+       <paper-slider min="0"
+                     max="255"
+                     step="1"
+                     value="{{sliderWriteValue}}"
+                     immediate-value="{{value}}"></paper-slider>
+     </span>
+     <!--  Large might span multiple columns, and chrome won't
+      send events for those parts. Workaround: take it out of
+      the columns. -->
+     <light9-color-picker-float id="large"></light9-color-picker-float>
   </template>
   <script src="/lib/color/one-color.js"></script>
   <script>
@@ -167,28 +204,27 @@
            throw new Error('no match');
        }
    }
+
    
-   Polymer({
-       is: "light9-color-picker",
-       properties: {
-           color: {
-               type: String,
-               notify: true,
-           },
-           hueSatColor: { type: String, notify: true, value: '#000000' },
+   class Light9ColorPicker extends Polymer.Element {
+       static get is() { return "light9-color-picker"; }
+       static get properties() { return {
+           color: { type: String, notify: true },
+           hueSatColor: { type: String, notify: true, value: null },
            value: { type: Number, notify: true }, // 0..255
            sliderWriteValue: { type: Number, notify: true },
-       },
-       observers: [
+       }; }
+       static get observers() { return [
            'readColor(color)',
            'onValue(value)',
            'writeColor(hueSatColor, value)'
-       ],
-       displayed: function() {
+       ]; }
+       displayed() {
            // call this when the smallcrosshair first has a size
            this._updateSmallCrosshair();
-       },
-       attached: function() {
+       }
+       ready() {
+           super.ready();
            if (!window.pickerCanvases) {
                window.pickerCanvases = {
                    large: new RainbowCanvas(
@@ -203,27 +239,41 @@
                // color may have been set before our image came
                this._updateSmallCrosshair();
            }.bind(this));
-       },
-       onValue: function(value) {
+           this.$.large.onCanvasMove = this.onCanvasMove.bind(this);
+           this.$.large.hideLarge = this.hideLarge.bind(this);
+           document.body.append(this.$.large);
+           this.$.large.style.display = 'none';
+       }
+       disconnectedCallback() {
+           super.disconnectedCallback();
+           document.body.removeChild(this.$.large);
+       }
+       onValue(value) {
            let neverBlack = .1 + .9 * value / 255;
            this.$.smallRainbow.style.filter = `brightness(${neverBlack})`;
-       },
-       writeColor: function(hueSatColor, value) {
+       }
+       writeColor(hueSatColor, value) {
+           if (hueSatColor === null || this.pauseWrites) { return; }
            this.color = one.color(hueSatColor).value(value / 255).hex();
-       },
-       readColor: function(color) {
-           if (this.$.largeRainbowComp.style.display == 'block') {
+       }
+       readColor(color) {
+           if (this.$.large.style.display == 'block') {
                // for performance, don't do color searches on covered widget
                return;
            }
-           
+
+           this.pauseWrites = true;
            var colorValue = one.color(color).value() * 255;
            // writing back to immediate-value doesn't work on paper-slider
            this.sliderWriteValue = colorValue;
-           
+
+           // don't update this if only the value changed, or we desaturate
+           this.hueSatColor = one.color(color).value(1).hex();
+
            this._updateSmallCrosshair();
-       },
-       _updateSmallCrosshair: function() {
+           this.pauseWrites = false;
+       }
+       _updateSmallCrosshair() {
            try {
                var pos = this.small.posFor(this.color);
            } catch(e) {
@@ -231,49 +281,45 @@
                return;
            }
            this.moveSmallCrosshair(pos);
-       },
-       _floatLarge: function() {
-           // Large might span multiple columns, and chrome won't
-           // send events for those parts. Workaround: take it out of
-           // the columns.
-           let large = this.$.largeRainbowComp;
-           let rect = this.$.smallRainbowComp.getBoundingClientRect();
-           document.body.append(large);
-           large.style.position = 'fixed';
-           large.style.left = (rect.left) + 'px';
-           large.style.top = (rect.top - 50) + 'px';
-       },
-       showLarge: function() {
-           this._floatLarge();
-           this.$.largeRainbowComp.style.display = 'block';
+       }
+       showLarge(x, y) {
+           this.$.large.style.display = 'block';
            try {
-               this.moveLargeCrosshair(this.large.posFor(this.color));
+               const pos = this.large.posFor(this.color);
+               this.moveLargeCrosshair(pos);
+               this.$.large.style.left = (x - Math.max(20, Math.min(380, pos[0]))) + 'px';
+               this.$.large.style.top = (y - Math.max(20, Math.min(180, pos[1]))) + 'px';
            } catch(e) {
                this.moveLargeCrosshair([-999, -999]);
+               this.$.large.style.left = (400 / 2) + 'px';
+               this.$.large.style.top = (200 / 2) + 'px';
                return;
            }
-       },
-       hideLarge: function() {
-           this.$.largeRainbowComp.style.display = 'none';
+       }
+       hideLarge() {
+           this.$.large.style.display = 'none';
            this.readColor(this.color);
-       },
-       onEnterSmall: function() {
-           // not if we just closed the large one
-           this.showLarge();
-       },
-       moveLargeCrosshair: function(pos, _elem) {
-           _elem = _elem || this.$.largeCrosshair;
+           this.closeTime = Date.now();
+       }
+       onEnterSmall(ev) {
+           if (this.closeTime && this.closeTime > Date.now() - 500) {
+               return;
+           }
+           this.showLarge(ev.pageX, ev.pageY);
+       }
+       moveLargeCrosshair(pos, _elem) {
+           _elem = _elem || this.$.large.shadowRoot.querySelector("#largeCrosshair");
            _elem.style.left = (pos[0] - _elem.offsetWidth / 2) + 'px';
            _elem.style.top = (pos[1] - _elem.offsetHeight / 2) + 'px';
-       },
-       moveSmallCrosshair: function(pos) {
+       }
+       moveSmallCrosshair(pos) {
            this.moveLargeCrosshair(pos, this.$.smallCrosshair);
-       },
-       onCanvasMove: function(ev) {
+       }
+       onCanvasMove(ev) {
            if (ev.buttons != 1) {
                return;
            }
-           var canvas = this.$.largeRainbow;
+           var canvas = this.$.large.shadowRoot.querySelector('#largeRainbow');
            var pos = [ev.offsetX - canvas.offsetLeft,
                       ev.offsetY - canvas.offsetTop];
            this.moveLargeCrosshair(pos);
@@ -283,8 +329,9 @@
            if (this.value == 0) {
                this.value = 255;
            }
-       },
-   });
+       }
+   }
+   customElements.define(Light9ColorPicker.is, Light9ColorPicker);
   </script>
 </dom-module>
 
--- a/light9/web/timeline/inline-attrs.coffee	Tue May 22 06:42:10 2018 +0000
+++ b/light9/web/timeline/inline-attrs.coffee	Wed May 23 09:53:07 2018 +0000
@@ -33,33 +33,34 @@
     @graph.runHandler(@update.bind(@), "update inline attrs #{@uri.value}")
     
   onColorScale: ->
-    return
+    return unless @uri? and @colorScale? and @colorScaleFromGraph?
     U = (x) => @graph.Uri(x)
     if @colorScale == @colorScaleFromGraph
       return
-    @editAttr(@song, @uri, U(':colorScale'), @graph.Literal(@colorScale))
+    @editAttr(@uri, U(':colorScale'), @graph.Literal(@colorScale))
 
-  editAttr: (song, note, attr, value) ->
+  editAttr: (note, attr, value) ->
     U = (x) => @graph.Uri(x)
-    if not song?
-      log("can't edit inline attr yet, no song")
+    if not @song?
+      log("inline: can't edit inline attr yet, no song")
       return
-    quad = (s, p, o) => {subject: s, predicate: p, object: o, graph: U(song)}
 
     existingColorScaleSetting = null
     for setting in @graph.objects(note, U(':setting'))
       ea = @graph.uriValue(setting, U(':effectAttr'))
-      if ea == attr
+      if ea.equals(attr)
         existingColorScaleSetting = setting
         
     if existingColorScaleSetting
-      @graph.patchObject(existingColorScaleSetting, U(':value'), value, U(song))
+      log('inline: update setting', existingColorScaleSetting.value)
+      @graph.patchObject(existingColorScaleSetting, U(':value'), value, U(@song))
     else
+      log('inline: new setting')
       setting = @graph.nextNumberedResource(note.value + 'set')
       patch = {delQuads: [], addQuads: [
-        quad(note, U(':setting'), setting)
-        quad(setting, U(':effectAttr'), attr)
-        quad(setting, U(':value'), value)
+        @graph.Quad(note, U(':setting'), setting, U(@song))
+        @graph.Quad(setting, U(':effectAttr'), attr, U(@song))
+        @graph.Quad(setting, U(':value'), value, U(@song))
         ]}
       @graph.applyAndSendPatch(patch)
     
@@ -72,7 +73,7 @@
     for setting in @graph.objects(@uri, U(':setting'))
       ea = @graph.uriValue(setting, U(':effectAttr'))
       value = @graph.stringValue(setting, U(':value'))
-      if ea == U(':colorScale')
+      if ea.equals(U(':colorScale'))
         @colorScaleFromGraph = value
         @colorScale = value
         existingColorScaleSetting = setting