Skip to content

Commit

Permalink
Update dimmer-button.js
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyflowed authored Dec 30, 2020
1 parent ab580cf commit 9d73719
Showing 1 changed file with 150 additions and 70 deletions.
220 changes: 150 additions & 70 deletions dimmer-button.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//TODO
//Add automatic area on <p bottom> when supported
//value template support
//Scale text when card is smaller than ~200px
//Select mode color
//Keep displaying newValue until the old value is updated
import {
LitElement,
html,
css
} from "https://unpkg.com/[email protected]/lit-element.js?module";

console.info('%c DIMMER-BUTTON %c 0.3 ','color: antiquewhite; background: #B565C6;','color: salmon; background: gray;');

class DimmerButton extends LitElement {

static get properties() {
Expand All @@ -20,14 +20,15 @@ class DimmerButton extends LitElement {
}

static getStubConfig() {
return { entity: '#Required',name: '#friendly_name',mode: '#supports "brightness" or "color_temp" for light and "volume" for media_player', bottom: "#optional text under name", height: "",background: "",foreground: "",icon: "",on_icon: "",off_icon: "",on_color: "",off_color: "" }
return { entity: '#Required',name: '#friendly_name',mode: '#supports "brightness" or "color_temp" for light and "volume" for media_player', direction: "horizontal", bottom: "#optional text under name", height: "",background: "",foreground: "",icon: "",on_icon: "",off_icon: "",on_color: "",off_color: "" }
}

constructor() {
super();
this.hold = false;
this.dim = false;
this.disabled = false;
this.move = false;
this.start = false;
this.delta = 3;
this.startY;
this.startX;
Expand All @@ -41,6 +42,9 @@ class DimmerButton extends LitElement {
this.maxVol;
this.newValue = 0;
this.longPress = null;
this.active = '';
this.cardWidth;
this.vertical = false;
}

entityConfig(entity) {
Expand Down Expand Up @@ -68,14 +72,14 @@ class DimmerButton extends LitElement {
this.iconOff = this.config.icon ? this.config.icon : this.config.off_icon ? this.config.off_icon : entity.attributes.icon ? entity.attributes.icon : "mdi:eye";
this.mode = "static";
this.displayState = entity.attributes.unit_of_measurement ? entity.attributes.unit_of_measurement: '';
this.disabled = true;
this.rangeMax = 0;
}else if(entity.entity_id.includes("media_player.")){
this.iconOn = this.config.icon ? this.config.icon : this.config.on_icon ? this.config.on_icon : entity.attributes.icon ? entity.attributes.icon : "mdi:cast";
this.iconOff = this.config.icon ? this.config.icon : this.config.off_icon ? this.config.off_icon : entity.attributes.icon ? entity.attributes.icon : "mdi:cast";
if(entity.attributes.supported_features & 4 && this.config.mode == "volume") {
this.mode = "volume";
this.displayState = (entity.state === "playing" ? '• '+(this.newValue != 0 ? this.newValue : Math.round((entity.attributes.volume_level*100)))+'%' : '');
this.maxVol = this.config.max_volume ? this.config.max_volume : 100;
this.rangeMax = this.maxVol;
this.rangeValue = (entity.attributes.volume_level*100);
}else{
Expand All @@ -92,21 +96,36 @@ class DimmerButton extends LitElement {
render() {
const entity = this.config.entity;
const entityStates = this.hass.states[entity]
let background = this.config.background ? this.config.background : "var(--ha-card-background)";
let foreground = this.config.foreground ? this.config.foreground : "var(--primary-color)";
const name = this.config.name ? this.config.name : entityStates.attributes.friendly_name;
const onColor = this.config.on_color ? this.config.on_color : "#fdd835";
const offColor = this.config.off_color ? this.config.off_color : "gray";
const cardHeight = this.config.height ? this.config.height : "150px";
const bottomText = this.config.bottom;
let bottomText = parseInt(cardHeight) >= 150 ? this.config.bottom : '';
let background = this.config.background ? this.config.background : "var(--ha-card-background)";
let foreground = this.config.foreground ? this.config.foreground : "var(--primary-color)";
let fontSizeH = parseInt(cardHeight) >= 150 ? "20px" : (20-((150-parseInt(cardHeight))/25))+"px";
let fontSizeW = this.cardWidth >= 200 ? "20px" : (20-((200-this.cardWidth)/12.5))+"px";
let fontSize = fontSizeH < fontSizeW ? fontSizeH : fontSizeW;
this.vertical = this.config.direction == 'vertical' ? true : false;
this.entityConfig(entityStates);
return html`
<ha-card>
<div class="button" style="${this.mode == "static" ? (entityStates.state == "on" ? "--dimmer-background:"+foreground : "--dimmer-background:"+background) : "--dimmer-background:"+background};--dimmer-foreground:${foreground};--color-on:${onColor};--color-off:${offColor};--card-height:${cardHeight};">
<p class="top ${entityStates.state}"><ha-icon class="icon" icon=${entityStates.state === "off" ? this.iconOff : this.iconOn}></ha-icon>${entityStates.state} ${this.displayState}</p>
<p class="middle">${name}</p>
${bottomText ? html`<p class="bottom">${bottomText}</p>`: ''}
<input type="range" ?disabled="${this.disabled}" min="0" max="${this.rangeMax}" class="${entityStates.state}" .value="${this.rangeValue}"
<div class="button ${this.active}" style="
${this.mode == "static" ? (entityStates.state == "on" ? "--dimmer-background:"+foreground : "--dimmer-background:"+background) : "--dimmer-background:"+background};
--dimmer-foreground:${foreground};
--color-on:${onColor};
--color-off:${offColor};
--card-height:${cardHeight};
--font-size:${fontSize};
--rotation:${this.vertical ? '270deg' : '0deg' };
${this.vertical ? "--range-width:"+cardHeight+"; --range-height:500px; --right:500px; --touch: none" : "--range-width: 100%; --range-height:100%; --right:0; --touch: pan-y;" };"
>
<div class="text">
<span class="top ${entityStates.state}"><ha-icon class="icon" icon=${entityStates.state === "off" ? this.iconOff : this.iconOn}></ha-icon>${entityStates.state} ${this.displayState}</span>
<span class="middle">${name}</span>
${bottomText ? html`<span class="bottom">${bottomText}</span>`: ''}
</div>
<input type="range" min="0" max="${entityStates.state !== "unavailable" ? this.rangeMax : "0" }" .value="${this.rangeValue}"
@pointerdown=${e => this._startCords(entity, e)}
@pointerup=${e => this._endCords(entityStates, e)}
@pointermove=${e => this._moveHandler(e)}
Expand All @@ -123,40 +142,49 @@ class DimmerButton extends LitElement {
let diffY = Math.abs(this.startY-e.pageY);
let posDelta = 6;
if(diffX > posDelta || diffY > posDelta){
clearTimeout(this.longPress);
if(this.start) {
this.move = true;
}
clearTimeout(this.longPress);
};
}

_displayValue(e) {
this.newValue = parseInt(e);
this.requestUpdate();
if(this.move){
this.newValue = parseInt(e);
this.requestUpdate();
}
}

_startCords(entity, e) {
this.startX = e.pageX;
this.startY = e.pageY;
this.clientY = e.clientY;
this.start = true;
this.active = "active";
let target = e.target.parentElement;
this.longPress = setTimeout(() => this._moreInfo('hass-more-info', { entityId: this.config.entity }, target), 600);
}

_endCords(entity, e) {
clearTimeout(this.longPress);
this.newValue = 0;
let diffX = Math.abs(e.pageX - this.startX);
let diffY = Math.abs(e.pageY - this.startY);
let scrollY = Math.abs(e.clientY - this.clientY);
this.move = false;
this.start = false;
this.active = '';
if(this.hold){
this.hold = false;
return false;
this.hold = false;
return false;
};
if((diffX < this.delta && diffY < this.delta)&&(e.button == 0 || e.button == undefined)){
this.dim = false;
this._toggle(entity);
}else{
this.dim = true;
this.dim = true;
};
if(scrollY > 50){
if(scrollY > 50 && !this.vertical){
this.dim = false;
}
}
Expand Down Expand Up @@ -204,113 +232,157 @@ class DimmerButton extends LitElement {
let num = 0;
if(this.dim){
switch(this.mode){
case "brightness":
this.hass.callService("homeassistant", "turn_on", {
entity_id: entity.entity_id,
brightness: value * 2.55
});
break;
case "color_temp":
num = Math.round(((entity.attributes.max_mireds-entity.attributes.min_mireds)*(value/100))+entity.attributes.min_mireds);
this.hass.callService("light", "turn_on", {
entity_id: entity.entity_id,
color_temp: num
});
break;
case "volume":
this.maxVol = this.config.max_volume ? this.config.max_volume : 100;
num = this.maxVol>value ? (value/100) : (this.maxVol/100);
this.hass.callService("media_player", "volume_set", {
entity_id: entity.entity_id,
volume_level: num
});
break;
case "pause":
case "toggle":
this._toggle(entity);
break;
case "brightness":
this.hass.callService("homeassistant", "turn_on", {
entity_id: entity.entity_id,
brightness: value * 2.55
});
break;
case "color_temp":
num = Math.round(((entity.attributes.max_mireds-entity.attributes.min_mireds)*(value/100))+entity.attributes.min_mireds);
this.hass.callService("light", "turn_on", {
entity_id: entity.entity_id,
color_temp: num
});
break;
case "volume":
num = this.maxVol>value ? (value/100) : (this.maxVol/100);
this.hass.callService("media_player", "volume_set", {
entity_id: entity.entity_id,
volume_level: num
});
break;
case "pause":
case "toggle":
this._toggle(entity);
break;
default:
}
}else{
e.target.value = this.rangeValue;
this.newValue = 0;
this.dim = false;
this.requestUpdate();
return false;
e.target.value = this.rangeValue;
this.newValue = 0;
this.dim = false;
this.requestUpdate();
return false;
}
this.dim = false;
}

updated(changedProperties) {
this.cardWidth = this.getBoundingClientRect().width;
if(!this.move){
this.newValue = 0;
}
}

setConfig(config) {
if (!config.entity) {
throw new Error("You need to define entity");
throw new Error("You need to define an entity");
}
this.config = config;
}

getCardSize() {
return 3;
const cardSize = this.config.height ? Math.round(parseInt(this.config.height)/50) : 3;
return cardSize;
}

static get styles() {
return css`
p{
position: relative;
ha-card{
background: none;
}
.text{
overflow: hidden;
display: flex;
flex-flow: column wrap;
padding-left: 6%;
height: 100%;
width: 94%;
}
span{
z-index: 1;
pointer-events: none;
text-transform: capitalize;
margin: 0;
}
p.off, p.paused, p.unavailable {
span.off, span.paused, span.unavailable {
color: var(--color-off);
}
p.on, p.playing {
span.on, span.playing {
color: var(--color-on);
}
.icon{
margin: 10px;
margin-right: 10px;
--mdc-icon-size: 30px;
top: -3px;
position: relative;
}
.top {
font-size: var(--paper-font-title_-_font-size);
padding: 30px 0 0 20px;
font-size: var(--font-size);
min-height: 35px;
max-height: 40px;
min-width: 40%;
flex-grow: 1;
padding-top: calc(var(--card-height) / 5);
padding-right: 5%;
margin-bottom: -20px;
}
.middle {
font-size: var(--paper-font-title_-_font-size);
font-size: var(--font-size);
font-weight: var(--paper-font-title_-_font-weight);
padding: 20px 0 5px 35px;
min-height: 30px;
max-height: 35px;
min-width: 50%;
flex-grow: 1;
padding-left: 1%;
padding-top: calc(3px + calc(var(--card-height) / 5));
}
.bottom {
font-size: var(--paper-font-body1_-_font-size);
font-weight: var(--paper-font-body1_-_font-weight);
padding: 5px 0 0 35px;
flex-grow: 10;
max-height: 40px;
padding-left: 1%;
padding-right: 10%;
white-space: nowrap;
}
.button {
height: var(--card-height);
width: 100%;
position: relative;
background: var(--dimmer-background);
background-size: cover;
border-radius: var(--ha-card-border-radius);
touch-action: pan-y;
touch-action: var(--touch);
overflow: hidden;
}
.button input[type="range"] {
border-radius: var(--ha-card-border-radius);
width: 100%;
margin: 0;
transition: box-shadow 0.2s ease-in-out;
overflow: hidden;
height: 100%;
-webkit-appearance: none;
background: none;
position: absolute;
width: var(--range-width);
height: var(--range-height);
top: 0;
right: 0;
right: var(--right);
-webkit-transform:rotate(var(--rotation));
-moz-transform:rotate(var(--rotation));
-o-transform:rotate(var(--rotation));
-ms-transform:rotate(var(--rotation));
transform:rotate(var(--rotation));
transform-origin: top right;
}
.button input[type="range"]::-webkit-slider-runnable-track {
Expand Down Expand Up @@ -345,11 +417,19 @@ class DimmerButton extends LitElement {
.button input[type="range"]:hover {
cursor: pointer;
}
.active{
-webkit-transform: scaleX(0.97) scaleY(0.95);
-ms-transform: scaleX(0.97) scaleY(0.95);
transform: scaleX(0.97) scaleY(0.95);
transition:all 0.3s ease-in;
}
span.effect {
position: absolute;
opacity: 0;
animation: ripple 200ms ease-in-out;
background-color: rgba(255, 255, 255, 0.9);
animation: ripple 200ms ease-in;
background-color: rgba(255, 255, 255, 0.7);
height: 100%;
width: 100%;
left: 0;
Expand Down

0 comments on commit 9d73719

Please sign in to comment.