vue 模拟LED数字电子显示,分段式
效果图
#led.vue
<template>
<div class="num-wrap">
<template v-for="(num, index) of numList">
<ul class="num-box" v-if="!num.isPoint" :style="{width: (fontSize*4/3)+'px', height: (fontSize*5/2)+'px'}">
<li v-for="(item, l) of num.list" :style="{width: item.width+'px', height: item.height+'px', left: item.left+'px', top: item.top+'px'}">
<div :style="{width: item.width+'px',height: item.height+'px'}" v-if="l%2 != 0">
<span style="display: inline-block; padding: 0; margin: 0; float: left; box-sizing: content-box;" class="numleft" :style="{borderWidth: item.height/2+'px ' + item.height/2 + 'px ' +item.height/2+'px 0', borderColor: 'transparent '+(item.isFront? frontColor : backColor) +' transparent transparent' }"></span>
<span style="display: inline-block; padding: 0; margin: 0; float: left;" :style="{width: (item.width-item.height) + 'px', height: item.height + 'px', background: item.isFront? frontColor : backColor}"></span>
<span style="display: inline-block; padding: 0; margin: 0; float: left; box-sizing: content-box;" class="numright" :style="{borderWidth: item.height/2+'px 0 ' + item.height/2 + 'px ' +item.height/2+'px', borderColor: 'transparent transparent transparent '+(item.isFront? frontColor : backColor) }"></span>
</div>
<div :style="{width: item.width+'px',height: item.height+'px'}" v-if="l%2 == 0">
<div style="padding: 0; margin: 0; box-sizing: content-box;" class="numtop" :style="{borderWidth: '0 ' + item.width/2+'px ' + item.width/2 + 'px ' +item.width/2+'px', borderColor: 'transparent transparent '+(item.isFront? frontColor : backColor) +' transparent' }"></div>
<div style="padding: 0; margin: 0px; box-sizing: content-box;" :style="{width: item.width + 'px', background: item.isFront? frontColor : backColor, height: (item.height-item.width) +'px'}"></div>
<div style="padding: 0; margin: 0; box-sizing: content-box;" class="numbottom" :style="{borderWidth: item.width/2+'px ' + item.width/2 + 'px 0 ' +item.width/2+'px', borderColor: (item.isFront? frontColor : backColor) +' transparent transparent transparent' }"></div>
</div>
</li>
</ul>
<ul v-if="num.isPoint" :style="{height: (fontSize*5/2)+'px'}">
<li v-for="(item, l) of num.list" :style="{marginTop: (fontSize*2 + item.height/2)+'px',height: item.height+'px', width: item.height+'px', background: item.color}"><span></span></li>
</ul>
</template>
</div>
</template>
<style>
.num-wrap ul{
list-style: none;
position: relative;
float: left;
margin-right: 10px;
}
.num-box>li{
position: absolute;
display: block;
}
.numleft{
width:0;
height: 0;
border-width:10px 10px 10px 0;
border-style:solid;
border-color:transparent #f00 transparent transparent;
}
.numright{
width: 0;
height: 0;
border-width: 10px 0 10px 10px;
border-style: solid;
border-color: transparent transparent transparent red;
}
.numtop{
position: relative;
z-index: 2;
width:0;
height:0;
border-width:0 10px 10px 10px;
border-style:solid;
border-color:transparent transparent red transparent;
}
.numbottom{
width:0;
height:0;
border-top: 10px solid red;
border-right: 10px solid transparent;
border-left: 10px solid transparent;
}
</style>
<script>
export default {
props: {
rect: {
type: Object,
default: () => {
return {}
}
}
},
data(){
return {
numArray: [],
numRulsArr: ["0 1 2 4 5 6","2 6","1 2 3 4 5","1 2 3 5 6","0 2 3 6","0 1 3 5 6","0 1 3 4 5 6","1 2 6","0 1 2 3 4 5 6","0 1 2 3 5 6", "3"],
numList: []
}
},
computed: {
val() {
return this.rect.options.data || 0;
},
fontSize() {
return this.rect.options.fontSize || 80;
},
frontColor() {
return this.rect.options.frontColor || 'rgba(0, 0, 0, .8)' ;
},
backColor() {
return this.rect.options.backColor || '#ccc' ;
},
digits() {
return this.rect.options.digits || 5;
}
},
watch: {
val(v){
this.createLedNum(v, {width: this.fontSize});
},
fontSize(val){
this.createNum(this.digits);
this.createLedNum(this.val, {width: val});
},
digits(val){
this.createNum(val);
this.createLedNum(this.val, {width: this.fontSize});
},
frontColor(){
this.createLedNum(this.val, {width: this.fontSize});
},
backColor(){
this.createNum(this.digits);
this.createLedNum(this.val, {width: this.fontSize});
}
},
methods: {
createNum(digits){
let width = this.fontSize;
let height = parseInt(width/4);
this.numList = [];
for(let m = 0; m < digits; m++){
this.numList.push({isPoint: false, num:'', codeNum: [], list:[
{width: height, height: width, left: 0, top: height*2/3, isFront: false, bg: ''},
{width: width, height: height, left: height*2/3, top: 0, isFront: false, bg: ''},
{width: height, height: width, left: width + height/3, top: height*2/3, isFront: false, bg: ''},
{width: width, height: height, left: height*2/3, top: width+parseInt(height/3), isFront: false, bg: ''},
{width: height, height: width, left: 0, top: width+height, isFront: false, bg: ''},
{width: width, height: height, left: height*2/3, top: width*2+height*2/3, isFront: false, bg: ''},
{width: height, height: width, left: width+parseInt(height/3), top: width+height, isFront: false, bg: ''}]
});
}
},
createLedNum(value, options){
let regPos = /^\d+(\.\d+)?$/; //非负浮点数
let regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; //负浮点数
if(regPos.test(value) || regNeg.test(value)) {
let width = options.width;
let height = width/4;
let valStr = value.toString();
let num= valStr.split('');
let offset = 0;
let len = num.length;
let digits = this.digits;
if(/\./.test(valStr)) {
digits +=1;
}
if(len < digits) offset = digits - len;
else if(len > digits) num = num.slice(0, digits);
for(let p=0; p < this.numList.length; p++){
if(this.numList[p].isPoint) {
this.numList.splice(p, 1);
break;
}
}
for(let o = 0; o < this.numList.length; o++){
for(let li of this.numList[o].list) {
li.isFront = false;
}
}
for(let m=0; m < num.length; m++){
let havePoint = false;
let n = num[m];
let str = '';
let cc = [];
if(/\d/.test(n)){
str = this.numRulsArr[n];
cc = str.split(' ');
}else if(/-/.test(n)){
str = this.numRulsArr[10];
cc = str.split(' ');
}else if(/\./.test(n)){
havePoint = true;
}
if(havePoint) {
this.numList.splice(m + offset, 0, {isPoint: true, num: '', codeNum: [], isFront: true, list: [{width: width, height: height, color: this.frontColor }]});
continue;
}
for(let i=0; i < 7; i++){
let isFront = false;
for(let j=0; j<cc.length; j++){
if(i == cc[j]) {
isFront = true;
break;
}else isFront = false;
}
if(isFront) this.numList[m + offset].list[i].isFront = true;
else this.numList[m + offset].list[i].isFront = false;
}
}
} else {
this.$Message.error({
content: '不是数值',
duration: 3
});
}
}
},
mounted(){
const _this = this;
this.createNum(this.digits);
this.createLedNum(this.val, {width: this.fontSize});
},
destroyed() {
var child = this.$el;
child.parentNode.removeChild(child);
}
}
</script>
使用
#引入
import led from './led.vue';
Vue.component('led', led);
<led :rect="rect"></led>
rect参数
{
options: {
data: 123.456, //要显示数字
fontSize: 80, //led字体大大小
frontColor: ‘rgba(227,47,47,.8)’,//前景色(数字颜色)
backColor: '#ccc', //背景色
digits: 5 //数字显示位数
}
}