| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <template>
- <div :class="classes" :style="{ height: Number(radius) * 2 + 'px', width: Number(radius) * 2 + 'px' }">
- <svg viewBox="0 0 100 100">
- <defs>
- <linearGradient :id="refRandomId" x1="100%" y1="0%" x2="0%" y2="0%">
- <stop v-for="(item, index) in stop" :key="index" :offset="item.key" :stop-color="item.value"></stop>
- </linearGradient>
- </defs>
- <path class="nut-circle-progress__path" :style="pathStyle" :d="path" fill="none" :stroke-width="strokeWidth">
- >
- </path>
- <path
- class="nut-circle-progress__hover"
- :style="hoverStyle"
- :d="path"
- fill="none"
- :stroke="hoverColor"
- :stroke-linecap="strokeLinecap"
- :stroke-width="strokeWidth"
- ></path>
- </svg>
- <div class="nut-circle-progress__text">
- <slot></slot>
- <div v-if="!slotDefault">{{ progress }}%</div>
- </div>
- </div>
- </template>
- <script lang="ts">
- import { computed, useSlots } from 'vue';
- import { createComponent } from '@/packages/utils/create';
- import { isObject } from '@/packages/utils/util';
- const { componentName, create } = createComponent('circle-progress');
- import type { PropType } from 'vue';
- export interface stopArr {
- key: string;
- value: string;
- }
- export default create({
- props: {
- progress: {
- type: [Number, String],
- required: true
- },
- strokeWidth: {
- type: [Number, String],
- default: 5
- },
- radius: {
- type: [Number, String],
- default: 50
- },
- strokeLinecap: {
- type: String as PropType<CanvasLineCap>,
- default: 'round'
- },
- color: {
- type: [String, Object],
- default: ''
- },
- pathColor: {
- type: String,
- default: ''
- },
- clockwise: {
- type: Boolean,
- default: true
- }
- },
- setup(props) {
- const slotDefault = !!useSlots().default;
- const refRandomId = Math.random().toString(36).slice(-8);
- const classes = computed(() => {
- const prefixCls = componentName;
- return {
- [prefixCls]: true
- };
- });
- const path = computed(() => {
- const isWise = props.clockwise ? 1 : 0;
- return `M 50 50 m 0 -45 a 45 45 0 1 ${isWise} 0 90 a 45 45 0 1, ${isWise} 0 -90`;
- });
- const hoverColor = computed(() => {
- return isObject(props.color) ? `url(#${refRandomId})` : props.color;
- });
- const hoverStyle = computed(() => {
- let perimeter = 283;
- let offset = (perimeter * Number(props.progress)) / 100;
- return {
- stroke: isObject(props.color) ? `url(#${refRandomId})` : props.color,
- strokeDasharray: `${offset}px ${perimeter}px`
- };
- });
- const pathStyle = computed(() => {
- return {
- stroke: props.pathColor
- };
- });
- const stop = computed(() => {
- if (!isObject(props.color)) {
- return;
- }
- let color = props.color;
- const colorArr = Object.keys(color).sort((a, b) => parseFloat(a) - parseFloat(b));
- let stopArr: stopArr[] = [];
- colorArr.map((item) => {
- let obj = {
- key: '',
- value: ''
- };
- obj.key = item;
- obj.value = color[item];
- stopArr.push(obj);
- });
- return stopArr;
- });
- return {
- classes,
- hoverStyle,
- pathStyle,
- path,
- hoverColor,
- stop,
- slotDefault,
- refRandomId
- };
- }
- });
- </script>
|