comparison web/light9-color-picker.ts @ 2376:4556eebe5d73

topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author drewp@bigasterisk.com
date Sun, 12 May 2024 19:02:10 -0700
parents light9/web/light9-color-picker.ts@18d6bdd422f2
children
comparison
equal deleted inserted replaced
2375:623836db99af 2376:4556eebe5d73
1 import debug from "debug";
2 import { css, html, LitElement, PropertyValueMap } from "lit";
3 import { customElement, property, queryAsync, state } from "lit/decorators.js";
4 import color from "onecolor";
5 import { ClientCoord, pickerFloat } from "./floating_color_picker";
6 export { Slider } from "@material/mwc-slider";
7
8 const log = debug("control.color");
9 type int8 = number;
10
11 @customElement("light9-color-picker")
12 export class Light9ColorPicker extends LitElement {
13 static styles = [
14 css`
15 :host {
16 position: relative;
17 display: flex;
18 align-items: center;
19 flex-wrap: wrap;
20 user-select: none;
21 }
22
23 #swatch {
24 display: inline-block;
25 width: 50px;
26 height: 30px;
27 margin-right: 3px;
28 border: 1px solid #333;
29 }
30
31 mwc-slider {
32 width: 160px;
33 }
34
35 #vee {
36 display: flex;
37 align-items: center;
38 }
39 `,
40 ];
41 render() {
42 return html`
43 <div id="swatch" style="background-color: ${this.color}; border-color: ${this.hueSatColor}" @mousedown=${this.startFloatingPick}></div>
44 <span id="vee"> V: <mwc-slider id="value" .value=${this.value} step="1" min="0" max="255" @input=${this.onVSliderChange}></mwc-slider> </span>
45 `;
46 }
47
48 // Selected color. Read/write. Equal to value*hueSatColor. Never null.
49 @property() color: string = "#000";
50
51 @state() hueSatColor: string = "#fff"; // always full value
52 @state() value: int8 = 0;
53
54 @queryAsync("#swatch") swatchEl!: Promise<HTMLElement>;
55
56 connectedCallback(): void {
57 super.connectedCallback();
58 pickerFloat.pageInit();
59 }
60 update(changedProperties: PropertyValueMap<this>) {
61 super.update(changedProperties);
62 if (changedProperties.has("color")) {
63 this.setColor(this.color);
64 }
65 if (changedProperties.has("value") || changedProperties.has("hueSatColor")) {
66 this.updateColorFromHSV();
67
68 this.dispatchEvent(new CustomEvent("input", { detail: { value: this.color } }));
69
70 this.swatchEl.then((sw) => {
71 sw.style.borderColor = this.hueSatColor;
72 });
73 }
74 }
75
76 private updateColorFromHSV() {
77 this.color = color(this.hueSatColor)
78 .value(this.value / 255)
79 .hex();
80 }
81
82 private onVSliderChange(ev: CustomEvent) {
83 this.value = ev.detail.value;
84 }
85
86 // for outside users of the component
87 setColor(col: string) {
88 if (col === null) throw new Error("col===null");
89 if (typeof col !== "string") throw new Error("typeof col=" + typeof col);
90 this.value = color(col).value() * 255;
91
92 // don't update this if only the value changed, or we desaturate
93 this.hueSatColor = color(col).value(1).hex();
94 }
95
96 private startFloatingPick(ev: MouseEvent) {
97 if (this.value < (20 as int8)) {
98 log("boost");
99 this.value = 255 as int8;
100 this.updateColorFromHSV();
101 }
102 pickerFloat.startPick(new ClientCoord(ev.clientX, ev.clientY), this.color, (hsc: string) => {
103 this.hueSatColor = hsc;
104 });
105 }
106 }