import { watch, computed } from 'vue';
import { raf, cancelRaf } from '@vant/use';
import { isObject, getSizeStyle, createNamespace } from '../utils';
import { BLUE, WHITE } from '../utils/constant';
const [createComponent, bem] = createNamespace('circle');
let uid = 0;
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
function getPath(clockwise, viewBoxSize) {
const sweepFlag = clockwise ? 1 : 0;
return `M ${viewBoxSize / 2} ${
viewBoxSize / 2
} m 0, -500 a 500, 500 0 1, ${sweepFlag} 0, 1000 a 500, 500 0 1, ${sweepFlag} 0, -1000`;
}
export default createComponent({
props: {
text: String,
strokeLinecap: String,
currentRate: {
type: Number,
default: 0,
},
speed: {
type: [Number, String],
default: 0,
},
size: {
type: [Number, String],
default: 100,
},
fill: {
type: String,
default: 'none',
},
rate: {
type: [Number, String],
default: 100,
},
layerColor: {
type: String,
default: WHITE,
},
color: {
type: [String, Object],
default: BLUE,
},
strokeWidth: {
type: [Number, String],
default: 40,
},
clockwise: {
type: Boolean,
default: true,
},
},
emits: ['update:currentRate'],
setup(props, { emit, slots }) {
const id = `van-circle-${uid++}`;
const viewBoxSize = computed(() => +props.strokeWidth + 1000);
const path = computed(() => getPath(props.clockwise, viewBoxSize.value));
watch(
() => props.rate,
(rate) => {
let rafId;
const startTime = Date.now();
const startRate = props.currentRate;
const endRate = format(rate);
const duration = Math.abs(((startRate - endRate) * 1000) / props.speed);
const animate = () => {
const now = Date.now();
const progress = Math.min((now - startTime) / duration, 1);
const rate = progress * (endRate - startRate) + startRate;
emit('update:currentRate', format(parseFloat(rate.toFixed(1))));
if (endRate > startRate ? rate < endRate : rate > endRate) {
rafId = raf(animate);
}
};
if (props.speed) {
cancelRaf(rafId);
rafId = raf(animate);
} else {
emit('update:currentRate', endRate);
}
},
{ immediate: true }
);
const renderHover = () => {
const style = {
fill: props.fill,
stroke: props.layerColor,
strokeWidth: `${props.strokeWidth}px`,
};
return