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";
const DEFAULT_MIN_KELVIN = 2700;
const DEFAULT_MAX_KELVIN = 6500;
export const DEFAULT_MIN_KELVIN = 2700;
export const DEFAULT_MAX_KELVIN = 6500;
export const temperature2rgb = (
temperature: number

View File

@ -1,10 +1,14 @@
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 { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
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";
const SAFE_ZONE_FACTOR = 0.9;
@ -79,10 +83,10 @@ class HaTempColorPicker extends LitElement {
public value?: number;
@property({ type: Number })
public min = 2000;
public min = DEFAULT_MIN_KELVIN;
@property({ type: Number })
public max = 10000;
public max = DEFAULT_MAX_KELVIN;
@query("#canvas") private _canvas!: HTMLCanvasElement;

View File

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

View File

@ -1,6 +1,14 @@
import { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing } from "lit";
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 { stateActive } from "../../../common/entity/state_active";
import "../../../components/ha-control-slider";
@ -57,6 +65,13 @@ class HuiLightColorTempTileFeature
? this.stateObj.attributes.color_temp_kelvin
: 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`
<div class="container">
<ha-control-slider
@ -66,13 +81,38 @@ class HuiLightColorTempTileFeature
.disabled=${this.stateObj!.state === UNAVAILABLE}
@value-changed=${this._valueChanged}
.label=${this.hass.localize("ui.card.light.color_temperature")}
.min=${this.stateObj.attributes.min_color_temp_kelvin!}
.max=${this.stateObj.attributes.max_color_temp_kelvin!}
.min=${minKelvin}
.max=${maxKelvin}
style=${styleMap({
"--gradient": gradient,
})}
></ha-control-slider>
</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) {
ev.stopPropagation();
const value = ev.detail.value;
@ -86,11 +126,10 @@ class HuiLightColorTempTileFeature
static get styles() {
return css`
ha-control-slider {
--control-slider-color: var(--tile-color);
--control-slider-background: -webkit-linear-gradient(
left,
rgb(255, 160, 0) 0%,
white 50%,
rgb(166, 209, 255) 100%
var(--gradient)
);
--control-slider-background-opacity: 1;
--control-slider-thickness: 40px;