mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-11 11:26:35 +00:00
Change color of state-badge icon according to rgb or brightness (#436)
* Change color of state-badge icon according to rgb or brightness * Remove unneeded edit * Set minimum brightness at 15%. Clear previous timeout
This commit is contained in:
parent
b1c83a8491
commit
acf853f713
@ -1,4 +1,4 @@
|
|||||||
<link rel='import' href='../../../bower_components/polymer/polymer.html'>
|
<link rel='import' href='../../../bower_components/polymer/polymer-element.html'>
|
||||||
|
|
||||||
<link rel='import' href='./ha-state-icon.html'>
|
<link rel='import' href='./ha-state-icon.html'>
|
||||||
|
|
||||||
@ -45,45 +45,95 @@
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
Polymer({
|
class StateBadge extends Polymer.Element {
|
||||||
is: 'state-badge',
|
static get is() { return 'state-badge'; }
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
stateObj: {
|
||||||
|
type: Object,
|
||||||
|
observer: 'updateIconColor',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
properties: {
|
computeDomain(stateObj) {
|
||||||
stateObj: {
|
|
||||||
type: Object,
|
|
||||||
observer: 'updateIconColor',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
computeDomain: function (stateObj) {
|
|
||||||
return window.hassUtil.computeDomain(stateObj);
|
return window.hassUtil.computeDomain(stateObj);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
_rgbFromBrightness(brightness) {
|
||||||
|
// Set icon bbroghtness to a scale between 15% bright to 100% bright.
|
||||||
|
const iconBrightness = (brightness + 45) / (255 + 45);
|
||||||
|
const hostBrightness = 1 - iconBrightness;
|
||||||
|
const re = /rgb\((\d+), (\d+), (\d+)\)/;
|
||||||
|
const rgbIconMatch = window.getComputedStyle(this.$.icon).color.match(re);
|
||||||
|
const rgbHostMatch = window.getComputedStyle(this).color.match(re);
|
||||||
|
let rgb;
|
||||||
|
if (rgbIconMatch && rgbHostMatch) {
|
||||||
|
const rgbIcon = rgbIconMatch.slice(1).map(v => Number.parseInt(v, 10));
|
||||||
|
const rgbHost = rgbHostMatch.slice(1).map(v => Number.parseInt(v, 10));
|
||||||
|
rgb = [
|
||||||
|
Math.round((rgbIcon[0] * iconBrightness) + (rgbHost[0] * hostBrightness)),
|
||||||
|
Math.round((rgbIcon[1] * iconBrightness) + (rgbHost[1] * hostBrightness)),
|
||||||
|
Math.round((rgbIcon[2] * iconBrightness) + (rgbHost[2] * hostBrightness)),
|
||||||
|
];
|
||||||
|
if (rgb.some(v => Number.isNaN(v))) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when an attribute changes that influences the color of the icon.
|
* Called when an attribute changes that influences the color of the icon.
|
||||||
*/
|
*/
|
||||||
updateIconColor: function (newVal) {
|
updateIconColor(newVal) {
|
||||||
|
const icon = this.$.icon;
|
||||||
// hide icon if we have entity picture
|
// hide icon if we have entity picture
|
||||||
if (newVal.attributes.entity_picture) {
|
if (newVal.attributes.entity_picture) {
|
||||||
this.style.backgroundImage = 'url(' + newVal.attributes.entity_picture + ')';
|
this.style.backgroundImage = 'url(' + newVal.attributes.entity_picture + ')';
|
||||||
this.$.icon.style.display = 'none';
|
icon.style.display = 'none';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.style.backgroundImage = '';
|
if (this._timeoutId) {
|
||||||
this.$.icon.style.display = 'inline';
|
window.clearTimeout(this._timeoutId);
|
||||||
|
this._timeoutId = null;
|
||||||
// for domain light, set color of icon to light color if available and it is
|
|
||||||
// not very white (sum rgb colors < 730)
|
|
||||||
if (window.hassUtil.computeDomain(newVal) === 'light' &&
|
|
||||||
newVal.state === 'on' &&
|
|
||||||
newVal.attributes.rgb_color &&
|
|
||||||
newVal.attributes.rgb_color.reduce(function (cur, tot) { return cur + tot; }, 0) < 730) {
|
|
||||||
this.$.icon.style.color = 'rgb(' + newVal.attributes.rgb_color.join(',') + ')';
|
|
||||||
} else {
|
|
||||||
this.$.icon.style.color = null;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
});
|
this.style.backgroundImage = '';
|
||||||
|
icon.style.display = 'inline';
|
||||||
|
if (newVal.state === 'unavailable') return;
|
||||||
|
let rgb;
|
||||||
|
let oldColor;
|
||||||
|
if (newVal.attributes.rgb_color) {
|
||||||
|
rgb = newVal.attributes.rgb_color;
|
||||||
|
} else if (newVal.attributes.brightness && newVal.attributes.brightness !== 255) {
|
||||||
|
if (icon.style.color !== '') {
|
||||||
|
oldColor = icon.style.color;
|
||||||
|
icon.style.transition = 'none';
|
||||||
|
icon.style.color = '';
|
||||||
|
}
|
||||||
|
rgb = this._rgbFromBrightness(newVal.attributes.brightness);
|
||||||
|
}
|
||||||
|
// Set color of icon to rgb color if available and it is not very white (sum rgb colors < 730)
|
||||||
|
if (rgb && rgb.reduce((cur, tot) => cur + tot, 0) < 730) {
|
||||||
|
if (oldColor) {
|
||||||
|
icon.style.color = oldColor;
|
||||||
|
}
|
||||||
|
// If we had to cancel transition - wait after restoring old color so transition will start
|
||||||
|
// from oldColor and not from css 'on' color.
|
||||||
|
if (icon.style.transition && oldColor) {
|
||||||
|
this._timeoutId = window.setTimeout(() => {
|
||||||
|
icon.style.transition = '';
|
||||||
|
icon.style.color = 'rgb(' + rgb.join(',') + ')';
|
||||||
|
}, 10);
|
||||||
|
} else {
|
||||||
|
icon.style.color = 'rgb(' + rgb.join(',') + ')';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
icon.style.color = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define(StateBadge.is, StateBadge);
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user