Use gradient based on min/max color temp for tile card feature (#17612)

This commit is contained in:
Paul Bottein 2023-08-21 13:03:20 +02:00 committed by GitHub
parent e8bd77a84e
commit dddee87de3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 13 deletions

View File

@ -1,7 +1,7 @@
import { clamp } from "../number/clamp"; import { clamp } from "../number/clamp";
const DEFAULT_MIN_KELVIN = 2700; export const DEFAULT_MIN_KELVIN = 2700;
const DEFAULT_MAX_KELVIN = 6500; export const DEFAULT_MAX_KELVIN = 6500;
export const temperature2rgb = ( export const temperature2rgb = (
temperature: number temperature: number

View File

@ -1,10 +1,14 @@
import { DIRECTION_ALL, Manager, Pan, Tap } from "@egjs/hammerjs"; import { DIRECTION_ALL, Manager, Pan, Tap } from "@egjs/hammerjs";
import { css, html, LitElement, PropertyValues, svg } from "lit"; import { LitElement, PropertyValues, css, html, svg } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map"; import { styleMap } from "lit/directives/style-map";
import { rgb2hex } from "../common/color/convert-color"; import { rgb2hex } from "../common/color/convert-color";
import { temperature2rgb } from "../common/color/convert-light-color"; import {
DEFAULT_MAX_KELVIN,
DEFAULT_MIN_KELVIN,
temperature2rgb,
} from "../common/color/convert-light-color";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
const SAFE_ZONE_FACTOR = 0.9; const SAFE_ZONE_FACTOR = 0.9;
@ -79,10 +83,10 @@ class HaTempColorPicker extends LitElement {
public value?: number; public value?: number;
@property({ type: Number }) @property({ type: Number })
public min = 2000; public min = DEFAULT_MIN_KELVIN;
@property({ type: Number }) @property({ type: Number })
public max = 10000; public max = DEFAULT_MAX_KELVIN;
@query("#canvas") private _canvas!: HTMLCanvasElement; @query("#canvas") private _canvas!: HTMLCanvasElement;

View File

@ -16,6 +16,10 @@ import {
LightEntity, LightEntity,
} from "../../../../data/light"; } from "../../../../data/light";
import { HomeAssistant } from "../../../../types"; import { HomeAssistant } from "../../../../types";
import {
DEFAULT_MAX_KELVIN,
DEFAULT_MIN_KELVIN,
} from "../../../../common/color/convert-light-color";
declare global { declare global {
interface HASSDomEvents { interface HASSDomEvents {
@ -37,12 +41,17 @@ class LightColorTempPicker extends LitElement {
return nothing; return nothing;
} }
const minKelvin =
this.stateObj.attributes.min_color_temp_kelvin ?? DEFAULT_MIN_KELVIN;
const maxKelvin =
this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN;
return html` return html`
<ha-temp-color-picker <ha-temp-color-picker
@value-changed=${this._ctColorChanged} @value-changed=${this._ctColorChanged}
@cursor-moved=${this._ctColorCursorMoved} @cursor-moved=${this._ctColorCursorMoved}
.min=${this.stateObj.attributes.min_color_temp_kelvin!} .min=${minKelvin}
.max=${this.stateObj.attributes.max_color_temp_kelvin!} .max=${maxKelvin}
.value=${this._ctPickerValue} .value=${this._ctPickerValue}
> >
</ha-temp-color-picker> </ha-temp-color-picker>

View File

@ -1,6 +1,14 @@
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import { rgb2hex } from "../../../common/color/convert-color";
import {
DEFAULT_MAX_KELVIN,
DEFAULT_MIN_KELVIN,
temperature2rgb,
} from "../../../common/color/convert-light-color";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { stateActive } from "../../../common/entity/state_active"; import { stateActive } from "../../../common/entity/state_active";
import "../../../components/ha-control-slider"; import "../../../components/ha-control-slider";
@ -57,6 +65,13 @@ class HuiLightColorTempTileFeature
? this.stateObj.attributes.color_temp_kelvin ? this.stateObj.attributes.color_temp_kelvin
: undefined; : undefined;
const minKelvin =
this.stateObj.attributes.min_color_temp_kelvin ?? DEFAULT_MIN_KELVIN;
const maxKelvin =
this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN;
const gradient = this.generateTemperatureGradient(minKelvin!, maxKelvin);
return html` return html`
<div class="container"> <div class="container">
<ha-control-slider <ha-control-slider
@ -66,13 +81,38 @@ class HuiLightColorTempTileFeature
.disabled=${this.stateObj!.state === UNAVAILABLE} .disabled=${this.stateObj!.state === UNAVAILABLE}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
.label=${this.hass.localize("ui.card.light.color_temperature")} .label=${this.hass.localize("ui.card.light.color_temperature")}
.min=${this.stateObj.attributes.min_color_temp_kelvin!} .min=${minKelvin}
.max=${this.stateObj.attributes.max_color_temp_kelvin!} .max=${maxKelvin}
style=${styleMap({
"--gradient": gradient,
})}
></ha-control-slider> ></ha-control-slider>
</div> </div>
`; `;
} }
private generateTemperatureGradient = memoizeOne(
(min: number, max: number) => {
const count = 10;
const gradient: [number, string][] = [];
const step = (max - min) / count;
const percentageStep = 1 / count;
for (let i = 0; i < count + 1; i++) {
const value = min + step * i;
const hex = rgb2hex(temperature2rgb(value));
gradient.push([percentageStep * i, hex]);
}
return gradient
.map(([stop, color]) => `${color} ${(stop as number) * 100}%`)
.join(", ");
}
);
private _valueChanged(ev: CustomEvent) { private _valueChanged(ev: CustomEvent) {
ev.stopPropagation(); ev.stopPropagation();
const value = ev.detail.value; const value = ev.detail.value;
@ -86,11 +126,10 @@ class HuiLightColorTempTileFeature
static get styles() { static get styles() {
return css` return css`
ha-control-slider { ha-control-slider {
--control-slider-color: var(--tile-color);
--control-slider-background: -webkit-linear-gradient( --control-slider-background: -webkit-linear-gradient(
left, left,
rgb(255, 160, 0) 0%, var(--gradient)
white 50%,
rgb(166, 209, 255) 100%
); );
--control-slider-background-opacity: 1; --control-slider-background-opacity: 1;
--control-slider-thickness: 40px; --control-slider-thickness: 40px;