uniapp 如何实现环形进度条

在uniapp中如何实现环形进度条效果?需要支持动态调整进度值,并且能自定义颜色、宽度等样式。最好能提供示例代码或推荐可用的组件库,谢谢!

2 回复

在 UniApp 中实现环形进度条,可以用以下两种方法:

  1. 使用 Canvas 绘制

    • canvas 组件上绘制圆形进度条。
    • 通过 uni.createCanvasContext 创建画布上下文。
    • 使用 arc 方法绘制背景圆环和进度圆环,通过 setLineDash 设置虚线可实现渐变效果。
    • 动态修改进度值并调用 draw 方法更新。
  2. 使用 CSS 实现

    • 利用 borderborder-radius 画一个圆形。
    • 通过 conic-gradient 背景实现环形渐变(注意兼容性)。
    • 或用两个半圆通过 rotate 旋转拼接成环形,通过 clip 控制显示范围。

简单示例(Canvas 方法)

// 在 template 中添加 <canvas canvas-id="progress"></canvas>
drawProgress(percent) {
  const ctx = uni.createCanvasContext('progress')
  const x = 50, y = 50, r = 40
  // 画背景圆环
  ctx.arc(x, y, r, 0, 2 * Math.PI)
  ctx.setStrokeStyle('#eee')
  ctx.stroke()
  // 画进度圆环
  ctx.beginPath()
  ctx.arc(x, y, r, -Math.PI/2, 2 * Math.PI * percent - Math.PI/2)
  ctx.setStrokeStyle('#007aff')
  ctx.stroke()
  ctx.draw()
}

推荐使用 Canvas 方法,兼容性更好且灵活。


在 UniApp 中实现环形进度条可以通过以下两种常用方法:


方法一:使用 Canvas 绘制

通过 canvas 组件动态绘制环形进度条,适合需要高度自定义的场景。

实现步骤:

  1. 在模板中添加 canvas 组件。
  2. 使用 JavaScript 计算并绘制进度条。

示例代码:

<template>
  <view>
    <canvas canvas-id="progressCanvas" class="canvas"></canvas>
    <text>{{ progress }}%</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      progress: 75, // 进度值(0-100)
      ctx: null
    };
  },
  mounted() {
    this.ctx = uni.createCanvasContext('progressCanvas', this);
    this.drawProgress();
  },
  methods: {
    drawProgress() {
      const { progress, ctx } = this;
      const width = 150; // 画布宽度
      const lineWidth = 8; // 进度条宽度
      const radius = (width - lineWidth) / 2; // 半径

      // 清除画布
      ctx.clearRect(0, 0, width, width);

      // 绘制背景圆环
      ctx.setStrokeStyle('#e5e5e5');
      ctx.setLineWidth(lineWidth);
      ctx.arc(width / 2, width / 2, radius, 0, 2 * Math.PI);
      ctx.stroke();

      // 绘制进度圆环
      const angle = (progress / 100) * 2 * Math.PI;
      ctx.setStrokeStyle('#007aff');
      ctx.setLineCap('round');
      ctx.beginPath();
      ctx.arc(width / 2, width / 2, radius, -Math.PI / 2, angle - Math.PI / 2);
      ctx.stroke();

      // 绘制文字(可选)
      ctx.setFillStyle('#333');
      ctx.setFontSize(16);
      ctx.setTextAlign('center');
      ctx.fillText(`${progress}%`, width / 2, width / 2 + 6);

      ctx.draw();
    }
  }
};
</script>

<style>
.canvas {
  width: 150px;
  height: 150px;
}
</style>

方法二:使用 CSS 和 SVG

通过 CSS 动画和 SVG 实现,性能较好且代码简洁。

示例代码:

<template>
  <view class="progress-ring">
    <svg :width="size" :height="size" class="svg">
      <!-- 背景圆环 -->
      <circle
        :cx="size/2"
        :cy="size/2"
        :r="radius"
        stroke="#e5e5e5"
        :stroke-width="strokeWidth"
        fill="none"
      />
      <!-- 进度圆环 -->
      <circle
        :cx="size/2"
        :cy="size/2"
        :r="radius"
        stroke="#007aff"
        :stroke-width="strokeWidth"
        fill="none"
        :stroke-dasharray="circumference"
        :stroke-dashoffset="dashOffset"
        stroke-linecap="round"
      />
    </svg>
    <text class="progress-text">{{ progress }}%</text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      progress: 75, // 进度值
      size: 150,    // SVG 尺寸
      strokeWidth: 8 // 圆环宽度
    };
  },
  computed: {
    radius() {
      return (this.size - this.strokeWidth) / 2;
    },
    circumference() {
      return 2 * Math.PI * this.radius;
    },
    dashOffset() {
      return this.circumference * (1 - this.progress / 100);
    }
  }
};
</script>

<style>
.progress-ring {
  position: relative;
  display: inline-block;
}
.svg {
  transform: rotate(-90deg); /* 从顶部开始 */
}
.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
}
</style>

使用建议:

  • Canvas 方案:适合动态进度、复杂交互或需要兼容低版本系统的场景。
  • CSS/SVG 方案:代码更简洁,性能更优,推荐在支持 SVG 的环境中使用。

根据项目需求选择合适的方法即可快速实现环形进度条。

回到顶部