Files @ 9b101d8bd7ea
Branch filter:

Location: light9/web/light9-color-picker.ts

drewp@bigasterisk.com
discover annotated lights in blender; send their color to the graph (temporary stmt)
import debug from "debug";
import { css, html, LitElement, PropertyValueMap } from "lit";
import { customElement, property, queryAsync, state } from "lit/decorators.js";
import color from "onecolor";
import { ClientCoord, pickerFloat } from "./floating_color_picker";
export { Slider } from "@material/mwc-slider";

const log = debug("control.color");
type int8 = number;

@customElement("light9-color-picker")
export class Light9ColorPicker extends LitElement {
  static styles = [
    css`
      :host {
        position: relative;
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        user-select: none;
      }

      #swatch {
        display: inline-block;
        width: 50px;
        height: 30px;
        margin-right: 3px;
        border: 1px solid #333;
      }

      mwc-slider {
        width: 160px;
      }

      #vee {
        display: flex;
        align-items: center;
      }
    `,
  ];
  render() {
    return html`
      <div id="swatch" style="background-color: ${this.color}; border-color: ${this.hueSatColor}" @mousedown=${this.startFloatingPick}></div>
      <span id="vee"> V: <mwc-slider id="value" .value=${this.value} step="1" min="0" max="255" @input=${this.onVSliderChange}></mwc-slider> </span>
    `;
  }

  // Selected color. Read/write. Equal to value*hueSatColor. Never null.
  @property() color: string = "#000";

  @state() hueSatColor: string = "#fff"; // always full value
  @state() value: int8 = 0;

  @queryAsync("#swatch") swatchEl!: Promise<HTMLElement>;

  connectedCallback(): void {
    super.connectedCallback();
    pickerFloat.pageInit();
  }
  update(changedProperties: PropertyValueMap<this>) {
    super.update(changedProperties);
    if (changedProperties.has("color")) {
      this.setColor(this.color);
    }
    if (changedProperties.has("value") || changedProperties.has("hueSatColor")) {
      this.updateColorFromHSV();

      this.dispatchEvent(new CustomEvent("input", { detail: { value: this.color } }));

      this.swatchEl.then((sw) => {
        sw.style.borderColor = this.hueSatColor;
      });
    }
  }

  private updateColorFromHSV() {
    this.color = color(this.hueSatColor)
      .value(this.value / 255)
      .hex();
  }

  private onVSliderChange(ev: CustomEvent) {
    this.value = ev.detail.value;
  }

  // for outside users of the component
  setColor(col: string) {
    if (col === null) throw new Error("col===null");
    if (typeof col !== "string") throw new Error("typeof col=" + typeof col);
    this.value = color(col).value() * 255;

    // don't update this if only the value changed, or we desaturate
    this.hueSatColor = color(col).value(1).hex();
  }

  private startFloatingPick(ev: MouseEvent) {
    if (this.value < (20 as int8)) {
      log("boost");
      this.value = 255 as int8;
      this.updateColorFromHSV();
    }
    pickerFloat.startPick(new ClientCoord(ev.clientX, ev.clientY), this.color, (hsc: string) => {
      this.hueSatColor = hsc;
    });
  }
}