diff --git a/dimmer-button.js b/dimmer-button.js
index 8f69066..e49b1e2 100644
--- a/dimmer-button.js
+++ b/dimmer-button.js
@@ -1,15 +1,15 @@
//TODO
//Add automatic area on
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/lit-element@2.0.1/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() {
@@ -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;
@@ -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) {
@@ -68,7 +72,6 @@ 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";
@@ -76,6 +79,7 @@ class DimmerButton extends LitElement {
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{
@@ -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`
-
-
${entityStates.state} ${this.displayState}
-
${name}
- ${bottomText ? html`
${bottomText}
`: ''}
-
+
+ ${entityStates.state} ${this.displayState}
+ ${name}
+ ${bottomText ? html`${bottomText}`: ''}
+
+
this._startCords(entity, e)}
@pointerup=${e => this._endCords(entityStates, e)}
@pointermove=${e => this._moveHandler(e)}
@@ -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;
}
}
@@ -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 {
@@ -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;