Mercurial > code > home > repos > light9
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 } |