diff options
author | Kyle Gunger <kgunger12@gmail.com> | 2024-11-13 04:18:23 -0500 |
---|---|---|
committer | Kyle Gunger <kgunger12@gmail.com> | 2024-11-13 04:18:23 -0500 |
commit | 049dc24ec02f3a14377d833ebf60efc4de12d918 (patch) | |
tree | 1a771f9ed743c96ee1d272cb746847e394c1a60e | |
parent | 74a8430a3334570e1dce4c112b166c80923f8402 (diff) |
Thermostat widget JS
-rw-r--r-- | index.html | 5 | ||||
-rw-r--r-- | scripts/gui-common/color.js | 10 | ||||
-rw-r--r-- | scripts/gui-common/widgets.js | 163 | ||||
-rw-r--r-- | scripts/main.js | 2 | ||||
-rw-r--r-- | styles/widgets.css | 4 |
5 files changed, 177 insertions, 7 deletions
@@ -33,11 +33,6 @@ </nav> <content> - <div class="widget thermostat" style="--percent: 0.3; --arch-color: #0084ff;"> - <arch></arch> - <gague>68</gague> - <temp>72°</temp> - </div> <div class="widget sel-button h"> <div class="widget button">Heat</div> <div class="widget button">Cool</div> diff --git a/scripts/gui-common/color.js b/scripts/gui-common/color.js index 0b25f68..b2d255a 100644 --- a/scripts/gui-common/color.js +++ b/scripts/gui-common/color.js @@ -91,6 +91,16 @@ class Color return L.interpolate(out, s); } + + hsv_angle() + { + // TODO + } + + hsv_mag() + { + // TODO + } } const RED = new Color(1, 0, 0, 1); diff --git a/scripts/gui-common/widgets.js b/scripts/gui-common/widgets.js index bedbc11..34660f4 100644 --- a/scripts/gui-common/widgets.js +++ b/scripts/gui-common/widgets.js @@ -567,6 +567,8 @@ class WidgetColorWheel extends WidgetDragable this.#detail = document.createElement("div"); this.#detail.classList.add("detail"); this.element.appendChild(this.#detail); + + this.addEventListener("change", this.#change); } /** @@ -605,6 +607,12 @@ class WidgetColorWheel extends WidgetDragable this.update_detail(tmpX, tmpY, mag); } + #change () + { + this.#tmpColor = this.get(); + + } + update_detail(x, y, mag) { if (x == 0) @@ -623,6 +631,161 @@ class WidgetColorWheel extends WidgetDragable } } +/** + * @typedef {object} ThermSpec + * @property {number} temp + * @property {number} gague + */ + +class WidgetThermostat extends Widget +{ + /** @type {HTMLElement} */ + #gague = null; + + /** @type {HTMLElement} */ + #temp = null; + + /** @type {number} */ + #deviation = null; + + /** @type {Color} */ + #cold_color = null; + + /** @type {Color} */ + #temperate_color = null; + + /** @type {Color} */ + #hot_color = null; + + /** @type {number} */ + #cold_temp = null; + + /** @type {number} */ + #temp_hot = null; + + /** + * Constructor + * @param {ThermSpec} therm Initial thermal information + * @param {number} [dev] The deviation of the arch (how far in degrees (temperature) from the middle to each end of the arc) + * @param {Color} [cold] The color the arch will display when in "cold" temperatures + * @param {Color} [temp] The color the arch will display when in "temperate" temperatures + * @param {Color} [hot] The color the arch will display when in "hot" temperatures + * @param {number} [ct] The point at which we swap from cold to temperate + * @param {number} [th] The point at which we swap from temperate to hot + */ + constructor( + therm, + dev = 7, + cold = Color.from_rgb(0, 133, 255), + temp = Color.from_rgb(18, 229, 82), + hot = Color.from_rgb(255, 149, 0), + ct = -2, + th = 2 + ) { + super(); + + this.element.classList.add("thermostat"); + this.element.appendChild(document.createElement("arch")); + + this.#temp = document.createElement("temp"); + this.element.appendChild(this.#temp); + + this.#gague = document.createElement("gague"); + this.element.appendChild(this.#gague); + + this.addEventListener("change", this.#update_ui); + + this.#deviation = dev; + this.#cold_color = cold; + this.#temperate_color = temp; + this.#hot_color = hot; + this.#cold_temp = ct; + this.#temp_hot = th; + this.set(therm); + } + + #update_ui() + { + /** @type {ThermSpec} */ + let therm = this.get(); + this.#gague.innerText = `${Math.fround(therm.gague)}`; + this.#temp.innerText = `${Math.fround(therm.temp)}°`; + + // Generate a percentage relative to the deviation + let div = (therm.gague - therm.temp) / this.#deviation; + // Normalize into range of 0 - 1 + div = div / 2 + 0.5; + div = Math.min(1, Math.max(div, 0)); + + this.element.style.setProperty("--percent", div); + + let color = this.#cold_color; + let r = therm.gague - therm.temp; + if (r >= this.#temp_hot) + color = this.#hot_color + else if (r >= this.#cold_temp) + color = this.#temperate_color; + this.element.style.setProperty("--detail", color.rgb()); + } + + /** + * Set the number shown underneath the thermostat's arch + * @param {number} t + */ + setTemp(t) + { + let therm = this.get(); + therm.temp = t; + this.set(therm); + } + + /** + * Set the number shown underneath the thermostat's arch + * @param {number} t + */ + setGague(g) + { + let therm = this.get(); + therm.gague = g; + this.set(therm); + } + + /** + * Set both the number underneath the thermostat and + * the number in the gague over it. + * @param {number} t + * @param {number} g + */ + setTherm(t, g) + { + this.set({temp: t, gague: g}); + } + + /** + * Colors which will display within the designated zones + * @param {Color} cold + * @param {Color} temperate + * @param {Color} hot + */ + setColors(cold, temperate, hot) + { + this.#cold_color = cold; + this.#temperate_color = temperate; + this.#hot_color = hot; + } + + /** + * Set the relative temperatures (in whatever degree units are being used) + * for when the color transitions happen on the arch + * @param {number} ct + * @param {number} th + */ + setZoneStops(ct, th) + { + + } +} + /** @typedef {Widget<number> & {getGague: () => number, setGague: (value: number) => void}} WidgetThermostat */ /** @typedef {Widget<any> & {addSelection: (name: string, value: any) => void, setSelection: (name: string) => boolean, removeSelection: (name: string) => void, getSelection: () => string}} WidgetSelectButton */ diff --git a/scripts/main.js b/scripts/main.js index 3cdbe12..cedfb79 100644 --- a/scripts/main.js +++ b/scripts/main.js @@ -18,6 +18,8 @@ class Client { content.appendChild(this.light.element); this.wheel = new WidgetColorWheel(); content.appendChild(this.wheel.element); + this.therm = new WidgetThermostat({temp: 72, gague: 69}); + content.appendChild(this.therm.element); // content.appendChild(Widget("button").el); // content.appendChild(Widget("checkbox").el); // content.appendChild(Widget("slider").el); diff --git a/styles/widgets.css b/styles/widgets.css index 5a7728e..79ef3ff 100644 --- a/styles/widgets.css +++ b/styles/widgets.css @@ -468,7 +468,7 @@ input { display: block; height: 100px; width: 200px; - background-color: var(--arch-color); + background-color: var(--detail); transform-origin: bottom center; transform: rotate(calc((1 - var(--percent)) * -144deg - 18deg)); transition-duration: 0.5s; @@ -488,7 +488,7 @@ input { box-sizing: border-box; border: 2px solid white; - box-shadow: inset 0px 0px 0px 2px var(--arch-color); + box-shadow: inset 0px 0px 0px 2px var(--detail); transform-origin: 13px 108px; transform: rotate(calc(72deg - (1 - var(--percent)) * 144deg)); |