116 lines
3.3 KiB
JavaScript
116 lines
3.3 KiB
JavaScript
import PropTypes from '../../_util/vue-types'
|
|
import { initDefaultProps } from '../../_util/props-util'
|
|
import enhancer from './enhancer'
|
|
import { propTypes, defaultProps } from './types'
|
|
|
|
const circlePropTypes = {
|
|
...propTypes,
|
|
gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
|
|
gapDegree: PropTypes.number,
|
|
}
|
|
|
|
const circleDefaultProps = {
|
|
...defaultProps,
|
|
gapPosition: 'top',
|
|
}
|
|
|
|
const Circle = {
|
|
props: initDefaultProps(circlePropTypes, circleDefaultProps),
|
|
methods: {
|
|
getPathStyles () {
|
|
const { percent, strokeWidth, gapDegree = 0, gapPosition } = this.$props
|
|
const radius = 50 - (strokeWidth / 2)
|
|
let beginPositionX = 0
|
|
let beginPositionY = -radius
|
|
let endPositionX = 0
|
|
let endPositionY = -2 * radius
|
|
switch (gapPosition) {
|
|
case 'left':
|
|
beginPositionX = -radius
|
|
beginPositionY = 0
|
|
endPositionX = 2 * radius
|
|
endPositionY = 0
|
|
break
|
|
case 'right':
|
|
beginPositionX = radius
|
|
beginPositionY = 0
|
|
endPositionX = -2 * radius
|
|
endPositionY = 0
|
|
break
|
|
case 'bottom':
|
|
beginPositionY = radius
|
|
endPositionY = 2 * radius
|
|
break
|
|
default:
|
|
}
|
|
const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
|
|
a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
|
|
a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`
|
|
const len = Math.PI * 2 * radius
|
|
const trailPathStyle = {
|
|
strokeDasharray: `${len - gapDegree}px ${len}px`,
|
|
strokeDashoffset: `-${gapDegree / 2}px`,
|
|
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s',
|
|
}
|
|
const strokePathStyle = {
|
|
strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,
|
|
strokeDashoffset: `-${gapDegree / 2}px`,
|
|
transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', // eslint-disable-line
|
|
}
|
|
return { pathString, trailPathStyle, strokePathStyle }
|
|
},
|
|
},
|
|
render () {
|
|
const {
|
|
prefixCls, strokeWidth, trailWidth, strokeColor,
|
|
trailColor, strokeLinecap, percent, ...restProps
|
|
} = this.$props
|
|
const { pathString, trailPathStyle, strokePathStyle } = this.getPathStyles()
|
|
delete restProps.percent
|
|
delete restProps.gapDegree
|
|
delete restProps.gapPosition
|
|
const pathFirst = {
|
|
attrs: {
|
|
'd': pathString,
|
|
'stroke': trailColor,
|
|
'stroke-width': trailWidth || strokeWidth,
|
|
'fill-opacity': '0',
|
|
},
|
|
class: `${prefixCls}-circle-trail`,
|
|
style: trailPathStyle,
|
|
}
|
|
const pathSecond = {
|
|
attrs: {
|
|
'd': pathString,
|
|
'stroke-linecap': strokeLinecap,
|
|
'stroke': strokeColor,
|
|
'stroke-width': percent === 0 ? 0 : strokeWidth,
|
|
'fill-opacity': '0',
|
|
},
|
|
class: `${prefixCls}-circle-path`,
|
|
style: strokePathStyle,
|
|
ref: 'svgPathRef',
|
|
}
|
|
return (
|
|
<svg
|
|
class={`${prefixCls}-circle`}
|
|
viewBox='0 0 100 100'
|
|
{...restProps}
|
|
>
|
|
<path
|
|
{...pathFirst}
|
|
/>
|
|
{
|
|
percent > 0 ? (
|
|
<path
|
|
{...pathSecond}
|
|
/>
|
|
) : null
|
|
}
|
|
</svg>
|
|
)
|
|
},
|
|
}
|
|
|
|
export default enhancer(Circle)
|