DEV Community

Arno Solo
Arno Solo

Posted on

Ring progress bar

Image description

<RingProgressBar :progress="progress" :rotate-angle="-90"/>
<input type="number" v-model="progress" step="10" min="0" max="100">
Enter fullscreen mode Exit fullscreen mode
<script setup lang="ts">
import { computed } from 'vue';

interface Props {
  progress: number; // 0 ~ 100
  size?: number;
  rotateAngle?: number; // start angle 0 ~ 360
  strokeWidth?: number;
  bgStrokeColor?: string;
  strokeColor?: string;
}

const props = withDefaults(defineProps<Props>(), {
  size: 100,
  rotateAngle: 0,
  bgStrokeColor: '#EAEFF4',
  strokeColor: '#ffaa00',
  strokeWidth: 8

})

const r = 43
const perimeter = r * 2 * Math.PI
const dashoffset = computed(() => {
  let progress = props.progress
  if(progress > 100) progress = 100
  if(progress < 0) progress = 0
  return perimeter * (1- progress/100)
})
</script>

<template>
  <svg :width="size" :height="size" :style="{'color': strokeColor}" viewBox="-50 -50 100 100">
    <circle cx="0" cy="0" :r="r" :stroke-width="strokeWidth" fill="none" :stroke="bgStrokeColor" />
    <circle cx="0" cy="0" :r="r" :stroke-width="strokeWidth" fill="none" stroke="currentColor"
      :stroke-dashoffset="dashoffset"
      :stroke-dasharray="`${perimeter}, ${perimeter}`"
      stroke-linecap='round'
      :transform="`rotate(${rotateAngle})`"
    />
  </svg>
</template>

<style scoped>
</style>

Enter fullscreen mode Exit fullscreen mode

Top comments (0)