现在我来详细讲解如何通过 JavaScript canvas 绘制动态圆环进度条的完整攻略。
概述
原理:利用 <canvas>
标签绘制一个圆环,再通过控制圆环的起始弧度和结束弧度来实现进度条的动态效果。
需要掌握的知识:
- HTML5
<canvas>
标签的使用 - ctx.beginPath()、ctx.closePath()、ctx.arc() 方法的使用
- setInterval() 方法的使用
步骤
第一步:创建HTML页面
在HTML页面中,我们需要构建一个 canvas元素,通过该元素完成我们的绘图任务:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript canvas绘制动态圆环进度条</title>
<style>
canvas {
display: block;
margin: auto;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>
代码解析:
<canvas>
标签是作为绘图容器出现的,除了 width 和 height 属性外,其他所有属性均为布尔型属性,都被默认为false。- 使用 CSS 样式将 canvas 元素居中。
第二步:绘制静态圆环
// 获取canvas元素
let canvas = document.getElementById('myCanvas');
// 获取绘图上下文
let ctx = canvas.getContext('2d');
// 根据canvas的大小计算圆的半径
let r = canvas.width / 2;
// 绘制背景圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#e1e1e1';
ctx.lineWidth = 10;
ctx.stroke();
// 绘制进度圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#f00';
ctx.lineWidth = 10;
ctx.stroke();
代码解析:
getContext('2d')
方法返回一个绘图上下文对象,该对象拥有丰富的绘制方法。- 通过绘制两个重叠的圆形来实现圆环进度条的效果,第一个圆为背景色,第二个圆为进度条。
- 圆环的宽度,可以通过 lineWidth 属性来控制。
第三步:绘制动态圆环
接下来,我们需要通过 JavaScript 控制圆环的起始弧度和结束弧度,从而实现动态的进度条效果。
// 设定初始弧度和结束弧度
let startAngle = -Math.PI /2;
let endAngle = -Math.PI /2;
// 设定绘制间隔(60帧每秒)
let speed = 60;
// 设定动画帧数
let frame = 0;
// 设定需要绘制的弧度
let arcs = Math.PI * 2 * 0.8;
// 执行动画
setInterval(function() {
// 让弧度按速度增长
endAngle = endAngle + Math.PI / (speed / 3);
// 每帧动画弧度增加的大小
let unitArc = arcs / (speed / 3);
// 绘制
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#e1e1e1';
ctx.lineWidth = 10;
ctx.stroke();
// 绘制进度圆
ctx.beginPath();
ctx.arc(r, r, r, startAngle, endAngle);
ctx.closePath();
ctx.strokeStyle = '#f00';
ctx.lineWidth = 10;
ctx.stroke();
// 更新起始弧度和结束弧度
startAngle = startAngle + unitArc;
frame++;
}, 1000 / speed);
代码解析:
- 通过 setInterval 方法设定固定帧速度,使得每隔 1000/60 秒会执行一次绘制圆环的函数。
- 动画的关键在于每帧增加的弧度,通过简单的计算得到一个逐渐递增的数量,从而实现动态展示的效果。
- 在每一次动画之前,首先使用 clearRect 方法清空画布,避免出现残留的进度条。
- 在绘制进度条的时候,起始弧度的值需要与结束弧度的值保持一致,这意味着,每次绘制都是在上一次的基础之上增加的,从而实现动态的效果。
示例
下面给出两个绘制动态圆环进度条的示例,可以帮助更好的理解动态圆环的实现方法。
示例1
本例在动态圆环进度条外围绘制了一个文字,该文字能够随进度条的进度进行变动。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>示例1 - JavaScript canvas绘制动态圆环进度条</title>
<style>
canvas {
display: block;
margin: auto;
}
#percent {
font-size: 30px;
font-weight: bold;
text-align: center;
margin-top: -75px;
color: #000;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="300" height="300"></canvas>
<div id="percent">0%</div>
<script>
// 获取canvas元素
let canvas = document.getElementById('myCanvas');
// 获取绘图上下文
let ctx = canvas.getContext('2d');
// 根据canvas的大小计算圆的半径
let r = canvas.width / 2;
// 设定初始弧度和结束弧度
let startAngle = -Math.PI /2;
let endAngle = -Math.PI /2;
// 设定绘制间隔(60帧每秒)
let speed = 60;
// 设定动画帧数
let frame = 0;
// 设定需要绘制的弧度
let arcs = Math.PI * 2 * 0.8;
// 执行动画
setInterval(function() {
// 让弧度按速度增长
endAngle = endAngle + Math.PI / (speed / 3);
// 每帧动画弧度增加的大小
let unitArc = arcs / (speed / 3);
// 更新百分比显示
let percent = Math.round((endAngle + Math.PI / 2) / (Math.PI * 2) * 100) + '%';
document.getElementById('percent').innerHTML = percent;
// 绘制
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#e1e1e1';
ctx.lineWidth = 10;
ctx.stroke();
// 绘制进度圆
ctx.beginPath();
ctx.arc(r, r, r, startAngle, endAngle);
ctx.closePath();
ctx.strokeStyle = '#f00';
ctx.lineWidth = 10;
ctx.stroke();
// 更新起始弧度和结束弧度
startAngle = startAngle + unitArc;
frame++;
}, 1000 / speed);
</script>
</body>
</html>
代码解析:
- 相对于基本版示例,本例唯一的区别在于增加了一个 div 元素,用于显示当前进度条的进度,元素样式方便修改。
- 在每次绘制的时候,动态地更新 div 元素中的文字,向用户展示当前进度条的具体进度。
示例2
本例在动态圆环进度条外围绘制了一个带有动画的箭头,该箭头能够随进度条的进度进行旋转,并且指向进度条的当前位置。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>示例2 - JavaScript canvas绘制动态圆环进度条</title>
<style>
canvas {
display: block;
margin: auto;
}
#arrow {
position: relative;
width: 100%;
height: 100%;
}
#arrow img {
position: absolute;
left: 50%;
top: 50%;
transform-origin: left center;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="300" height="300"></canvas>
<div id="arrow">
<img src="arrow.png" alt="">
</div>
<script>
// 获取canvas元素
let canvas = document.getElementById('myCanvas');
// 获取绘图上下文
let ctx = canvas.getContext('2d');
// 根据canvas的大小计算圆的半径
let r = canvas.width / 2;
// 设定初始弧度和结束弧度
let startAngle = -Math.PI /2;
let endAngle = -Math.PI /2;
// 设定绘制间隔(60帧每秒)
let speed = 60;
// 设定动画帧数
let frame = 0;
// 设定需要绘制的弧度
let arcs = Math.PI * 2 * 0.8;
// 获取箭头
let arrow = document.getElementById('arrow').getElementsByTagName('img')[0];
// 执行动画
setInterval(function() {
// 让弧度按速度增长
endAngle = endAngle + Math.PI / (speed / 3);
// 每帧动画弧度增加的大小
let unitArc = arcs / (speed / 3);
// 更新百分比显示
let percent = Math.round((endAngle + Math.PI / 2) / (Math.PI * 2) * 100);
// 绘制
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#e1e1e1';
ctx.lineWidth = 10;
ctx.stroke();
// 绘制进度圆
ctx.beginPath();
ctx.arc(r, r, r, startAngle, endAngle);
ctx.closePath();
ctx.strokeStyle = '#f00';
ctx.lineWidth = 10;
ctx.stroke();
// 绘制箭头
arrow.style.transform = `rotate(${percent / 100 * 360 + 90}deg)`;
// 更新起始弧度和结束弧度
startAngle = startAngle + unitArc;
frame++;
}, 1000 / speed);
</script>
</body>
</html>
代码解析:
- 相对于基本版示例,本例唯一的区别在于增加了一个 div 元素,并在该元素内部绘制了一个带有动画的箭头。
- 箭头的动态旋转效果是通过设置 transform 属性中的 rotate 值来实现的,在每次更新进度条的时候,调整 rotate 的值,即可实现箭头的动态旋转效果。
- 注意,需要设置 transform-origin 属性,将旋转点设置为箭头的左端中点。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript canvas绘制动态圆环进度条 - Python技术站