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`
V: `; } // 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; connectedCallback(): void { super.connectedCallback(); pickerFloat.pageInit(); } update(changedProperties: PropertyValueMap) { 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; }); } }