DemuMesDataV/components/digitalFlop/index.vue

195 lines
4.0 KiB
Vue

<template>
<div class="dv-digital-flop">
<canvas ref="digital-flop" />
</div>
</template>
<script>
import CRender from '@jiaminghi/c-render'
import '@jiaminghi/charts/lib/extend/index'
import { deepMerge } from '@jiaminghi/charts/lib/util/index'
import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'
export default {
name: 'DigitalFlop',
props: {
config: {
type: Object,
default: () => ({})
}
},
data () {
return {
render: null,
defaultConfig: {
/**
* @description Number for digital flop
* @type {Array<Number>}
* @default number = []
* @example number = [10]
*/
number: [],
/**
* @description Content formatter
* @type {String}
* @default content = ''
* @example content = '{nt}个'
*/
content: '',
/**
* @description Number toFixed
* @type {Number}
* @default toFixed = 0
*/
toFixed: 0,
/**
* @description Text align
* @type {String}
* @default textAlign = 'center'
* @example textAlign = 'center' | 'left' | 'right'
*/
textAlign: 'center',
/**
* @description Text style configuration
* @type {Object} {CRender Class Style}
*/
style: {
fontSize: 30,
fill: '#3de7c9'
},
/**
* @description CRender animationCurve
* @type {String}
* @default animationCurve = 'easeOutCubic'
*/
animationCurve: 'easeOutCubic',
/**
* @description CRender animationFrame
* @type {String}
* @default animationFrame = 50
*/
animationFrame: 50
},
mergedConfig: null,
graph: null
}
},
watch: {
config () {
const { update } = this
update()
}
},
methods: {
init () {
const { initRender, mergeConfig, initGraph } = this
initRender()
mergeConfig()
initGraph()
},
initRender () {
const { $refs } = this
this.render = new CRender($refs['digital-flop'])
},
mergeConfig () {
const { defaultConfig, config } = this
this.mergedConfig = deepMerge(deepClone(defaultConfig, true), config || {})
},
initGraph () {
const { getShape, getStyle, render, mergedConfig } = this
const { animationCurve, animationFrame } = mergedConfig
const shape = getShape()
const style = getStyle()
this.graph = render.add({
name: 'numberText',
animationCurve,
animationFrame,
shape,
style
})
},
getShape () {
const { number, content, toFixed, textAlign } = this.mergedConfig
const [w, h] = this.render.area
const position = [w / 2, h / 2]
if (textAlign === 'left') position[0] = 0
if (textAlign === 'right') position[0] = w
return {
number,
content,
toFixed,
position
}
},
getStyle () {
const { style, textAlign } = this.mergedConfig
return deepMerge(style, {
textAlign,
textBaseline: 'middle'
})
},
update () {
const { mergeConfig, mergeShape, getShape, getStyle, graph, mergedConfig } = this
mergeConfig()
if (!graph) return
const { animationCurve, animationFrame } = mergedConfig
const shape = getShape()
const style = getStyle()
mergeShape(graph, shape)
graph.animationCurve = animationCurve
graph.animationFrame = animationFrame
graph.animation('style', style, true)
graph.animation('shape', shape)
},
mergeShape (graph, shape) {
const cacheNum = graph.shape.number.length
const shapeNum = shape.number.length
if (cacheNum !== shapeNum) graph.shape.number = shape.number
}
},
mounted () {
const { init } = this
init()
}
}
</script>
<style lang="less">
.dv-digital-flop {
canvas {
width: 100%;
height: 100%;
}
}
</style>