vue中实现LED效果数字,公司业务需求,刚好要实现此效果,参考该文章(www.yisu.com/zixun/15676…
实现的效果如图:
实现思路
每一个数字由七个元素构成,即每一个segment元素。0~9 的数字都有自己的构成方式,用数组digitSegments数组表示。例如:
数字0用数组表示就是[1,2,3,4,5,6],通过设置动态行内样式,从而实现数字高亮效果。 每次设置最新数字对应的动态样式之前,先清除原来的样式。
实现代码:
<template>
<div class="led">
<div ref="ledBox" class="digit">
<div class="one segment" />
<div class="tow segment" />
<div class="three segment" />
<div class="four segment" />
<div class="five segment" />
<div class="six segment" />
<div class="seven segment" />
</div>
</div>
</template>
<script>
export default {
name: '',
props: {
num: { // 要显示的数字
type: [Number, String],
default: null
},
color: { // 要显示的数字颜色
type: String,
default: '#fff'
}
},
data() {
return {
digitSegments: [
[1, 2, 3, 4, 5, 6],
[2, 3],
[1, 2, 7, 5, 4],
[1, 2, 7, 3, 4],
[6, 7, 2, 3],
[1, 6, 7, 3, 4],
[1, 6, 5, 4, 3, 7],
[1, 2, 3],
[1, 2, 3, 4, 5, 6, 7],
[1, 2, 7, 3, 6]
]
}
},
watch: {
num(val) {
this.setNumber(this.$refs.ledBox, val)
},
color(){
this.setNumber(this.$refs.ledBox, this.num)
}
},
mounted() {
// 设置 初始值
this.setNumber(this.$refs.ledBox, this.num)
},
methods: {
// digit 所在元素、number 需要设置的数字
setNumber(digit, number) {
var that = this
var segments = digit.querySelectorAll('.segment')
var current = parseInt(digit.getAttribute('data-value'))
// 更新数字前 清除之前显示的数字
if (!isNaN(current) && current !== number) {
// 清空之前的数字 current为之前的数字
that.digitSegments[current].forEach(function(digitSegment, index) {
setTimeout(function() {
segments[digitSegment - 1].style.background = 'rgba(3, 0, 22, 0.2)'
}, index * 50)
})
}
if ((isNaN(current) || current !== number) && number != null) {
// 显示最新的数字
setTimeout(function() {
that.digitSegments[number].forEach(function(digitSegment, index) {
setTimeout(function() {
segments[digitSegment - 1].style.background = that.color
}, index * 50)
})
}, 250)
digit.setAttribute('data-value', number)
}
}
}
}
</script>
<style lang='scss' scoped>
.led {
display: inline-block;
height: 100px;
margin: 5px;
.digit {
display: inline-block;
position: relative;
box-sizing: border-box;
width: 68px;
height: 100px;
background: rgba(3, 0, 22, 0.2);
border: 1px solid #5a3fff;
box-shadow: inset 0px 0px 8px #5a3fff;
border-radius: 4px;
/* Inside auto layout */
flex: none;
order: 0;
flex-grow: 0;
.segment {
width: 30px;
height: 7px;
position: absolute;
background: rgba(204, 204, 204, 0.1);
border-radius: 2px;
transform: matrix(0, 1, 1, 0, 0, 0);
}
.one {
left: 20px;
top: 8px;
transform: rotate(0deg);
}
.tow {
left: 41px;
top: 25px;
}
.three {
left: 41px;
top: 62px;
}
.four {
left: 20px;
top: 81px;
transform: rotate(0deg);
}
.five {
left: -2px;
top: 63px;
}
.six {
left: -2px;
top: 26px;
}
.seven {
left: 20px;
top: 45.99px;
transform: rotate(0deg);
}
}
}
</style>
组件使用:
<template>
<div>
<Led v-for="(item,index) in ledData" :key="index" :num="item.num" :color="item.color" />
</div>
</template>
<script>
import Led from './Led.vue'
export default {
components: { Led },
data(){
return {
ledData: [
{
num: 2,
color: '#ff0000'
},{
num: 5,
color: 'yellow'
}
]
}
},
mounted(){
//实现效果: 每3秒更换显示数字以及颜色
setInterval(()=>{
this.handlerFn()
},3000)
},
methods: {
handlerFn(){
this.ledData.forEach(element => {
element.num = Math.floor(Math.random()*10)
element.color = this.randomColor()
});
},
randomColor() {//得到随机的颜色值
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return "rgb(" + r + "," + g + "," + b + ")";
}
}
}
</script>