summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2024-11-13 04:18:23 -0500
committerKyle Gunger <kgunger12@gmail.com>2024-11-13 04:18:23 -0500
commit049dc24ec02f3a14377d833ebf60efc4de12d918 (patch)
tree1a771f9ed743c96ee1d272cb746847e394c1a60e
parent74a8430a3334570e1dce4c112b166c80923f8402 (diff)
Thermostat widget JS
-rw-r--r--index.html5
-rw-r--r--scripts/gui-common/color.js10
-rw-r--r--scripts/gui-common/widgets.js163
-rw-r--r--scripts/main.js2
-rw-r--r--styles/widgets.css4
5 files changed, 177 insertions, 7 deletions
diff --git a/index.html b/index.html
index f5fd475..81722a9 100644
--- a/index.html
+++ b/index.html
@@ -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));