add percent arc component

This commit is contained in:
jiaming 2018-12-21 18:29:40 +08:00
parent 06dc1922ae
commit 700b617f57
2 changed files with 224 additions and 0 deletions

View File

@ -25,6 +25,7 @@ import columnChart from './columnChart/index.vue'
import numberShow from './numberShow/index.vue'
import percentPond from './percentPond/index.vue'
import percentArc from './percentArc/index.vue'
import waterLevelPond from './waterLevelPond/index.vue'
import scrollBoard from './scrollBoard/index.vue'
@ -58,6 +59,7 @@ export default function (Vue) {
Vue.component('numberShow', numberShow)
Vue.component('percentPond', percentPond)
Vue.component('percentArc', percentArc)
Vue.component('waterLevelPond', waterLevelPond)
Vue.component('scrollBoard', scrollBoard)

View File

@ -0,0 +1,222 @@
<template>
<div class="percent-arc">
<loading v-if="!percent || percent === 0" />
<div class="canvas-container">
<canvas :ref="ref" />
</div>
<div class="for-slot">
<slot></slot>
</div>
</div>
</template>
<script>
import canvasMixin from '../../mixins/canvasMixin.js'
export default {
name: 'PercentArc',
props: ['percent', 'ringColor', 'arcColor', 'ringLineWidth', 'arcLineWidth', 'radius', 'arcType'],
mixins: [canvasMixin],
data () {
return {
ref: `percent-arc-${(new Date()).getTime()}`,
defaultRadius: 0.9,
defaultRingLineWidth: 4,
defaultArcLineWidth: 10,
defaultArcType: 'butt',
defaultRingColor: '#00BAFF',
defaultArcColor: ['#00BAFF', '#3DE7C9'],
trueArcType: '',
trueRadius: 0,
ringRadius: 0,
arcRadius: 0,
trueRingColor: '',
trueArcColor: '',
trueRingLineWidth: 0,
trueArcLineWidth: 0
}
},
watch: {
percent () {
const { init } = this
init()
},
ringColor () {
const { init } = this
init()
},
arcColor () {
const { init } = this
init()
},
ringLineWidth () {
const { init } = this
init()
},
arcLineWidth () {
const { init } = this
init()
},
radius () {
const { init } = this
init()
},
arcType () {
const { init } = this
init()
}
},
methods: {
async init () {
const { initCanvas, draw } = this
await initCanvas()
draw()
},
draw () {
const { percent } = this
if (!percent && percent !== 0) return
const { clearCanvas } = this
clearCanvas()
const { calcLineWidth, calcRaidus, calcColors } = this
calcLineWidth()
calcRaidus()
calcColors()
const { calcArcType, drawRing, drawArc } = this
calcArcType()
drawRing()
drawArc()
},
calcLineWidth () {
const { defaultRingLineWidth, defaultArcLineWidth, ringLineWidth, arcLineWidth } = this
this.trueRingLineWidth = ringLineWidth || defaultRingLineWidth
this.trueArcLineWidth = arcLineWidth || defaultArcLineWidth
},
calcRaidus () {
const { radius, defaultRadius, canvasWH } = this
const trueRadius = this.trueRadius = radius || defaultRadius
const ringRadius = this.ringRadius = Math.min(...canvasWH) * trueRadius / 2
const { trueRingLineWidth, trueArcLineWidth } = this
const halfRingLineWidth = trueRingLineWidth / 2
const halfArcLineWidth = trueArcLineWidth / 2
this.arcRadius = ringRadius - halfRingLineWidth - halfArcLineWidth
},
calcColors () {
const { ringColor, defaultRingColor } = this
this.trueRingColor = ringColor || defaultRingColor
const { arcColor, defaultArcColor } = this
this.trueArcColor = arcColor || defaultArcColor
},
calcArcType () {
const { arcType, defaultArcType } = this
this.trueArcType = arcType || defaultArcType
},
drawRing () {
const { ringRadius, ctx, trueRingLineWidth, centerPos, trueRingColor } = this
ctx.lineWidth = trueRingLineWidth
ctx.strokeStyle = trueRingColor
ctx.beginPath()
ctx.arc(...centerPos, ringRadius, 0, Math.PI * 2)
ctx.stroke()
},
drawArc () {
const { ctx, centerPos, percent, trueArcType, canvasWH } = this
const { trueArcLineWidth, arcRadius, trueArcColor } = this
const { canvas: { getLinearGradientColor } } = this
const fullArc = Math.PI * 2
const offsetArc = Math.PI / 2
const arcBegin = offsetArc * -1
const arcEnd = fullArc * percent / 100 - offsetArc
ctx.lineCap = trueArcType
ctx.lineWidth = trueArcLineWidth
ctx.strokeStyle = getLinearGradientColor(ctx, [0, 0], [0, canvasWH[1]], trueArcColor)
ctx.beginPath()
ctx.arc(...centerPos, arcRadius, arcBegin, arcEnd)
ctx.stroke()
}
},
mounted () {
const { init } = this
init()
}
}
</script>
<style lang="less">
.percent-arc {
position: relative;
display: flex;
.canvas-container {
flex: 1;
canvas {
width: 100%;
height: 100%;
}
}
.for-slot {
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>