Some building blocks to play with:
Template:
<template>
<div class="level">
<div v-for="(color, index) in colors" :key="index" class="led" :ref="'dot-' + index +'-'+this.id"></div>
</div>
</template>
<script>
export default {
data(){
return {
//define me here
min:0,
max:100,
dark:0.4,
colors:["#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#4ed34e",
"#ffcf00",
"#ffcf00",
"#ffcf00",
"#ffcf00",
"red",
"red",
"red"],
//no need to change those
value:0,
inited:false
}
},
methods: {
getElement: function(name){
return this.$refs[name][0]
},
full: function(){
return Math.floor(this.colors.length*this.percentage/100)
},
half: function (){
let p = this.colors.length*this.percentage/100;
p -= this.full()
p *= .5
p += this.dark;
return p;
},
lit: function(){
if(this.inited == false){
return
}
this.colors.forEach((e,i) => {
let dot = this.getElement("dot-"+i+"-"+this.id);
if(!dot){
console.log("no dots found")
return
}
if(i<this.full()){
dot.style.filter= "brightness(1.1)";
}
else if(i==this.full()){
dot.style.filter = "brightness("+this.half()+")";
}
else{
dot.style.filter= "brightness("+this.dark+")";
}
})
}
},
watch: {
msg: function(){
if(this.msg.payload != undefined){
this.value = this.msg.payload
this.lit()
}
}
},
computed: {
formattedValue: function () {
return this.value.toFixed(2)
},
percentage: function(){
return Math.floor(((this.value - this.min) / (this.max - this.min)) * 100);
}
},
mounted(){
this.colors.forEach((c,i) => {
let dot = this.getElement("dot-"+i+"-"+this.id);
if(!dot){
console.log("no dots found")
return
}
dot.style.backgroundColor = c
}
)
this.inited = true;
},
}
</script>
CSS:
.level{
display: flex;
gap:2px;
}
.led {
background: #ffffff;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: inset 0px 0px 20px 0px #00000099, 0px 0px 3px 0px #00000099;
filter: brightness(0.4);
}