zhou zhou
5 小时以前 46d872c1a5b77aa8799de4a64888a0a24a1422d6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<!-- 进度条卡片 -->
<template>
  <div class="art-card h-32 flex flex-col justify-center px-5">
    <div class="mb-3.5 flex-c" :style="{ justifyContent: icon ? 'space-between' : 'flex-start' }">
      <div v-if="icon" class="size-11 flex-cc bg-g-300 text-xl rounded-lg" :class="iconStyle">
        <ArtSvgIcon :icon="icon" class="text-2xl"></ArtSvgIcon>
      </div>
      <div>
        <ArtCountTo
          class="mb-1 block text-2xl font-semibold"
          :target="percentage"
          :duration="2000"
          suffix="%"
          :style="{ textAlign: icon ? 'right' : 'left' }"
        />
        <p class="text-sm text-g-500">{{ title }}</p>
      </div>
    </div>
    <ElProgress
      :percentage="currentPercentage"
      :stroke-width="strokeWidth"
      :show-text="false"
      :color="color"
      class="[&_.el-progress-bar__outer]:bg-[rgb(240_240_240)]"
    />
  </div>
</template>
 
<script setup>
  defineOptions({ name: 'ArtProgressCard' })
  const props = defineProps({
    percentage: { required: true },
    title: { required: false },
    icon: { required: false },
    iconStyle: { required: false },
    strokeWidth: { required: false, default: 5 },
    color: { required: false, default: '#67C23A' }
  })
  const animationDuration = 500
  const currentPercentage = ref(0)
  const animateProgress = () => {
    const startTime = Date.now()
    const startValue = currentPercentage.value
    const endValue = props.percentage
    const animate = () => {
      const currentTime = Date.now()
      const elapsed = currentTime - startTime
      const progress = Math.min(elapsed / animationDuration, 1)
      currentPercentage.value = startValue + (endValue - startValue) * progress
      if (progress < 1) {
        requestAnimationFrame(animate)
      }
    }
    requestAnimationFrame(animate)
  }
  onMounted(() => {
    animateProgress()
  })
  watch(
    () => props.percentage,
    () => {
      animateProgress()
    }
  )
</script>