Changeset - 0c54bd6e1630
[Not reviewed]
default
0 2 0
Drew Perttula - 6 years ago 2019-06-01 21:16:47
drewp@bigasterisk.com
color picker no longer opens on hover, and no longer shows a rainbow in small mode.
Ignore-this: 637e296da9b59d81acf03eff16a4e193
you can also drag outside the large rainbow while picking and it'll snap to the closest
point.
2 files changed with 61 insertions and 76 deletions:
0 comments (0 inline, 0 general)
light9/web/light9-color-picker.html
Show inline comments
 
@@ -4,12 +4,18 @@
 
<dom-module id="light9-color-picker-float">
 
  <template>
 
    <style>
 
     :host {
 
         z-index: 10;
 
         position: fixed;
 
         width: 400px;
 
         height: 200px;
 
         border: 10px solid #000;
 
         box-shadow: 8px 11px 40px 0px rgba(0, 0, 0, 0.74);
 
         /* This display (and border-color) are replaced later. */
 
         display: none;
 
     }
 
     #largeCrosshair {
 
         position: absolute;
 
         left: -60px;
 
         top: -62px;
 
         pointer-events: none;
 
@@ -23,14 +29,12 @@
 
         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; 
 
@@ -39,13 +43,13 @@
 
     }
 
    </style>
 
    <div id="largeRainbowComp">
 
      <div id="largeRainbow"
 
           on-mousemove="onCanvasMove"
 
           on-mouseup="hideLarge"
 
           on-mouseleave="hideLarge"></div>
 
      ></div>
 
      <div id="largeCrosshair"></div>
 
    </div>
 
  </template>
 
  <script>
 
   class Light9ColorPickerFloat extends Polymer.Element {
 
     static get is() { return "light9-color-picker-float"; }
 
@@ -60,65 +64,60 @@
 
    <style>
 
     :host {
 
         position: relative;
 
         display: flex;
 
         align-items: center;
 
         flex-wrap: wrap;
 
     }
 
     #smallRainbowComp {
 
         display: inline-block;
 
         overflow: hidden;
 
         position: relative;
 
     }
 
     #smallRainbow {
 
         background: url(/colorpick_rainbow_small.png);
 
         width: 150px; 
 
         height: 30px;
 
         user-select: none;
 
     }
 
     
 
     #smallCrosshair {
 
         position: absolute;
 
         left: -60px;
 
         top: -62px;
 
         pointer-events: none;
 
     }
 
     #smallCrosshair {
 
         background: url(/colorpick_crosshair_small.svg);
 
         /* this can't be too tall, or chrome will cull it in the 
 
            second column if its top goes above the top of the columns */
 
         width: 400px; 
 
         height: 60px;
 
     }
 
     
 
     #smallRainbowComp {
 
     #swatch {
 
         display: inline-block;
 
         width: 150px; 
 
         height: 30px;
 
         margin-right: 3px;
 
         border: 1px solid #333;
 
     }
 
     
 
     paper-slider {
 
         width: 170px;
 
     }
 
     
 
     #vee {
 
         display: flex;
 
         align-items: center;
 
     }
 
     #large {
 
         display: none;
 
     
 
     #outOfBounds {
 
         user-select: none;
 
         z-index: 1;
 
         background: #00000060;
 
         position: fixed;
 
         left: 0;
 
         top: 0;
 
         width: 100%;
 
         height: 100%;
 
         display: none; /* Toggledlater. */
 
     }
 
    </style>
 
    <div id="smallRainbowComp">
 
      <div id="smallRainbow" on-mouseenter="onEnterSmall"></div>
 
      <div id="smallCrosshair"></div>
 
    </div>
 
    <div id="swatch" style="background-color: {{color}}"
 
         on-mousedown="onDownSmall"></div>
 
    <span id="vee">
 
      V:
 
      <paper-slider min="0"
 
                    max="255"
 
                    step="1"
 
                    value="{{sliderWriteValue}}"
 
                    immediate-value="{{value}}"></paper-slider>
 
    </span>
 
    <!-- Temporary scrim on the rest of the page. It looks like we're dimming
 
         the page to look pretty, but really this is so we can track the mouse
 
         when it's outside the large canvas. -->
 
    <div id="outOfBounds"
 
         on-mousemove="onOutOfBoundsMove"
 
         on-mouseup="hideLarge"></div>
 
    <!--  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>
 
@@ -220,51 +219,40 @@
 
     }; }
 
     static get observers() { return [
 
       'readColor(color)',
 
       'onValue(value)',
 
       'writeColor(hueSatColor, value)'
 
     ]; }
 
     displayed() {
 
       // call this when the smallcrosshair first has a size
 
       this._updateSmallCrosshair();
 
     }
 
     ready() {
 
       super.ready();
 
       if (!window.pickerCanvases) {
 
         window.pickerCanvases = {
 
           large: new RainbowCanvas(
 
             '/colorpick_rainbow_large.png', [400, 200]),
 
           small: new RainbowCanvas(
 
             '/colorpick_rainbow_small.png', [150, 30]),
 
             '/colorpick_rainbow_large.png', [400, 200]),           
 
         };
 
       }
 
       this.large = window.pickerCanvases.large;
 
       this.small = window.pickerCanvases.small;
 
       this.small.onLoad(function() {
 
         // color may have been set before our image came
 
         this._updateSmallCrosshair();
 
       }.bind(this));
 
       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) {
 
       if (this.hueSatColor === null) {
 
         this.hueSatColor = '#ffffff';
 
       }
 
       let neverBlack = .1 + .9 * value / 255;
 
       this.$.smallRainbow.style.filter = `brightness(${neverBlack})`;
 
       this.$.swatch.style.filter = `brightness(${neverBlack})`;
 
     }
 
     writeColor(hueSatColor, value) {
 
       if (hueSatColor === null || this.pauseWrites) { return; }
 
       this.color = one.color(hueSatColor).value(value / 255).hex();
 
       this.$.large.style.borderColor = this.color;
 
     }
 
     readColor(color) {
 
       if (this.$.large.style.display == 'block') {
 
         // for performance, don't do color searches on covered widget
 
         return;
 
       }
 
@@ -274,81 +262,78 @@
 
       // 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();
 
       this.pauseWrites = false;
 
     }
 
     _updateSmallCrosshair() {
 
       try {
 
         var pos = this.small.posFor(this.color);
 
       } catch(e) {
 
         this.moveSmallCrosshair([-999, -999]);
 
         return;
 
       }
 
       this.moveSmallCrosshair(pos);
 
     }
 
     }    
 
     showLarge(x, y) {
 
       this.$.large.style.display = 'block';
 
       this.$.outOfBounds.style.display = 'block';
 
       try {
 
         let pos;
 
         try {
 
           pos = this.large.posFor(this.color);
 
         } catch(e) {
 
           pos = [-999, -999];
 
         }
 
         this.moveLargeCrosshair(pos);
 
         this.$.large.style.left = (x - Math.max(60, Math.min(380, pos[0]))) + 'px';
 
         this.$.large.style.top = (y - Math.max(60, Math.min(180, pos[1]))) + 'px';
 
         this.$.large.style.left = (x - this.clamp(pos[0], 0, 400)) + 'px';
 
         this.$.large.style.top = (y - this.clamp(pos[1], 0, 200)) + 'px';
 
       } catch(e) {
 
         this.moveLargeCrosshair([-999, -999]);
 
         this.$.large.style.left = (400 / 2) + 'px';
 
         this.$.large.style.top = (200 / 2) + 'px';
 
         return;
 
       }
 
     }
 
     hideLarge() {
 
       this.$.large.style.display = 'none';
 
       this.$.outOfBounds.style.display = 'none';
 

	
 
       if (this.color !== undefined) {
 
         this.readColor(this.color);
 
       }
 
       this.closeTime = Date.now();
 
     }
 
     onEnterSmall(ev) {
 
       if (this.closeTime && this.closeTime > Date.now() - 500) {
 
         return;
 
       }
 

	
 
       // if scrolling put us here, don't open large. require deliberate entering motion.
 
       
 
     onDownSmall(ev) {
 
       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(pos) {
 
       this.moveLargeCrosshair(pos, this.$.smallCrosshair);
 
     moveLargeCrosshair(pos) {
 
       const ch = this.$.large.shadowRoot.querySelector("#largeCrosshair");
 
       ch.style.left = (pos[0] - ch.offsetWidth / 2) + 'px';
 
       ch.style.top = (pos[1] - ch.offsetHeight / 2) + 'px';
 
     }
 
     onCanvasMove(ev) {
 
       if (ev.buttons != 1) {
 
         this.hideLarge();
 
         return;
 
       }
 
       var canvas = this.$.large.shadowRoot.querySelector('#largeRainbow');
 
       var pos = [ev.offsetX - canvas.offsetLeft,
 
                  ev.offsetY - canvas.offsetTop];
 
       this.setLargePoint(pos);
 
     }
 
     setLargePoint(pos) {
 
       this.moveLargeCrosshair(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;
 
       }
 
     }
 
     onOutOfBoundsMove(ev) {
 
       const largeX = ev.offsetX - this.$.large.offsetLeft;
 
       const largeY = ev.offsetY - this.$.large.offsetTop;
 
       this.setLargePoint([this.clamp(largeX, 0, 400-1),
 
                           this.clamp(largeY, 0, 200-1)]);
 
     }
 
     clamp(x, lo, hi) {
 
       return Math.max(lo, Math.min(hi, x));
 
     }
 
   }
 
   customElements.define(Light9ColorPicker.is, Light9ColorPicker);
 
  </script>
 
</dom-module>
 

	
light9/web/light9-color-picker_test.html
Show inline comments
 
@@ -27,13 +27,13 @@
 
     const assert = chai.assert;
 
     
 
     describe("RainbowCanvas", () => {
 
       it("loads rainbow", (done) => {
 
         const rc = new RainbowCanvas('/colorpick_rainbow_large.png', [400, 200]);
 
         rc.onLoad(() => {
 
           assert.equal(rc.colorAt(200, 100), '#ff33ff');
 
           assert.equal(rc.colorAt([200, 100]), '#ff38eb');
 
           done();
 
         });
 
       });
 
     }); 
 
     mocha.run();
 
    </script>
0 comments (0 inline, 0 general)