Kros的博客 Kros的博客
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云

Kros

凡心所向,素履以往,生如逆旅,一苇以航
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云
  • CSS

  • JavaScript

  • 工具

  • Vue

    • vue批量引入组件
    • vue中watch用法
    • vue使用基础JSX语法
    • vue首页白屏
    • vue长列表优化
    • 模板文件中script、template、style存在必要性
    • popup弹窗组件
    • 使用$mount和extend扩展vue
    • 扩展toast合并popup(按需加载)
    • canvas实现弧形进度条
    • vue中使用CSS Modules
    • vue实现无限轮播图
    • vue半圆形菜单
    • 纯CSS实现圆形进度条
    • v-model简单实现
    • vue带箭头下拉框
    • vue事件修饰符
    • vue鼠标悬浮显示提示文字
    • vue添加发布版本号方法
    • vue配置全局样式文件
    • vue在env development中设置全局变量不生效
    • vue引入less或scss全局变量
    • vue中使用Keepalive
    • vue2为什么只支持一个根节点
    • vue打包优化分析工具—webpack-bundle-analyzer
    • vue使用echarts(按需加载)
    • echarts柱形图重合堆叠
    • vue使用draggable实现多列拖拽(解决空列不能拖拽问题)
    • vue禁止三方库打包到bundle中
    • npm run serve运行背后的思考
    • vxe-table树结构不允许insert
    • vue组件延迟加载
    • 多页面应用配置
    • vue项目常用优化
    • vue实现拖动拼图验证码
    • vue虚拟dom
    • canvas心形动画
    • canvas绘制玫瑰曲线
    • element表单validateField验证部分字段
    • element日期选择限制今天以后并精确到小时
    • 前端使用JSEncrypt和node-rsa进行rsa加密传输和接收解密
    • elementui日期选择器生日只选择月和日不选择年并隐藏年份
    • el-upload组件第二次点击手动submit时不生效
    • element表单内输入框使用@keyup enter native回车时会刷新页面
  • antdv踩坑记录

  • Vue3

  • 前端
  • Vue
kros
2021-01-04

canvas实现弧形进度条

最近项目中要实现可变进度条显示,首先想到这种可变化内容需要使用canvas来实现,折腾一番效果如下:

进度条

代码:

<template>
	<div class="container">
		<div class="score">
			<!-- uniapp写法 -->
			<!-- <canvas class="canvasb" canvas-id="canvasBgId"></canvas>
			<canvas class="canvasp" canvas-id="canvasId" ></canvas> -->
			<canvas class="canvasb" id="canvasBgId"></canvas>
			<canvas class="canvasp" id="canvasId" ></canvas>
			<div class="value">{{score}}</div>
		</div>
	</div>
</template>

<script>
	export default {
		data() {
			return  {
				score: 80
			}
		},
		methods: {
			// 绘制进度条背景
			drawProgressBg() {
				let ctx = document.getElementById('canvasBgId').getContext('2d');
				// let ctx = uni.createCanvasContext('canvasBgId', this);// uniapp写法
				 // 设置圆环宽度
				// ctx.setLineWidth(this.borderWidth);// uniapp写法
				ctx.lineWidth = this.borderWidth;
				// 线条颜色			
				// ctx.setStrokeStyle(this.progressBgColor); 	// uniapp写法
				ctx.strokeStyle = this.progressBgColor;
				// 表示进度的两端为圆形
				// ctx.setLineCap('round');// uniapp写法
				ctx.lineCap = 'round';
				ctx.beginPath(); 
				let radius = this.progressWidth / 2;
				ctx.arc(radius, radius, radius - this.borderWidth, this.startAngle, this.endAngle, false);
				ctx.stroke(); // 对路径进行描绘
				// ctx.draw();// uniapp写法
			},
			
			// 绘制进度条
			drawCircleByProgress(progress) {
				// 第一次操作进度环时将上下文保存到了this.data中,直接使用即可
				let ctx = this.progressContext;
				if (!ctx) {
					ctx = document.getElementById('canvasId').getContext('2d');
					// uniapp写法
					// ctx = uni.createCanvasContext('canvasId', this);
					this.progressContext = ctx;
				}
				// 表示进度的两端为圆形
				// ctx.setLineCap('round');// uniapp写法
				ctx.lineCap = 'round';
				// 设置线条的宽度和颜色
				// ctx.setLineWidth(this.borderWidth);// uniapp写法
				ctx.lineWidth = this.borderWidth;
				// ctx.setStrokeStyle(this.progressColor);// uniapp写法
				ctx.strokeStyle = this.progressColor;
				// 0.9Math.PI开始画图,到2.1Math.PI结束,
				let endAngle = ((this.endAngle - this.startAngle) / 100) * progress + this.startAngle;
				ctx.beginPath();
				// 半径为整个canvas宽度的一半
				let radius = this.progressWidth / 2;
				ctx.arc(radius, radius, radius - this.borderWidth, this.startAngle, endAngle, false);
				ctx.stroke();
				// ctx.draw();		// uniapp写法		
			},
		},
		created() {
			this.borderWidth = 8;
			this.progressWidth = 200;
			this.progressColor = '#4486FF';
			this.progressBgColor = '#ddd';
			this.progressContext = null;
			this.startAngle = 0.95 * Math.PI;
			this.endAngle = 2.05 * Math.PI;
		},
		mounted() {	
			this.drawProgressBg();
			this.drawCircleByProgress(this.score);
		}
	}
</script>

<style scoped lang="scss">
	.container {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		width: 100vw;
		height: 100vh;
		
		.score {
			position: relative;
			display: inline-flex;
			align-items: center;
			justify-content: center;
			width: 300px;
			height: 150px;
			.canvasb,.canvasp {
				position: absolute;
				top: 0;
				width: 300px;
				height: 150px;
			}
			
			.value {
				position: absolute;
				top: 40%;
				left: 28%;
				color: #4486FF;
				font-weight: bold;
				font-size: 32px;
			}
		}
	}
</style>

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#vue
上次更新: 2025/09/05, 8:09:00
扩展toast合并popup(按需加载)
vue中使用CSS Modules

← 扩展toast合并popup(按需加载) vue中使用CSS Modules→

最近更新
01
Find the next perfect square
09-05
02
Regex validate PIN code
09-05
03
Find the odd int
09-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 kros king
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
icon-heart-o icon-heart icon-infinity icon-pause icon-play link next prev