使用canvas绘制圆环进度条

技术要求

需要一点点数学基础
需要对 canvas 的常见的方法熟悉

一点点数学基础

已知圆心,半径,角度,求圆上的点坐标

canvas 常见的方法

菜鸟教程

扬帆起航

  1. 首先创建一个canvas ,并将这个dom添加在html中

方法名称:createCanvas

// 需要申明两个全局变量
let isIconLoadSuccess = false;
let iconLoading = null;// 以下是一个方法
const canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 300;
canvas.style.border = '1px #ccc solid';// 提前加载图标数据
const imgObj = new Image();
imgObj.src = './success-filling.png';
imgObj.onload = function () {isIconLoadSuccess = true;iconLoading = this;
};return canvas;
  1. 定义一个绘制圆环的方法

方法名称:drawCircle(ctx, config)

绘制圆环的思路
使用arc绘制一个圆形,在其内部填充一个样式,将圆的边框lineWidth设置的宽度大一点,这个宽度就是圆环的大小,设置strokeStyle的颜色,该颜色就是圆环的颜色,最后设置连接处样式lineCap,这里建议将lineCap设置成round
因为最终想要的是圆环,所以角度应该是(0,360)
最后调用strokeclosePath上色和关闭路径

const {x, y, radius, startAngle, endAngle, color, lineWidth,} = config;ctx.beginPath();ctx.arc(x, y, radius, startAngle, endAngle, false);// 设定曲线粗细度ctx.lineWidth = lineWidth;// 给曲线着色ctx.strokeStyle = color;// 连接处样式ctx.lineCap = 'round';// 给环着色ctx.stroke();ctx.closePath();
  1. 绘制圆环

方法名称:circle(percent = '0.0')

const { width, height } = canvas;
const ctx = canvas.getContext('2d');
// 清除画布
ctx.clearRect(0, 0, width, height);
// 保存
ctx.save();
/* 填充文字 */
ctx.font = '24px Microsoft YaHei';
/* 文字颜色 */
ctx.fillStyle = '#999';
/* 文字内容 */
const insertContent = '本月任务进度';
// 拿到文本内容的像素相关信息 单位长度(px)
const measureText = ctx.measureText(insertContent);
/* 插入文字,后面两个参数为文字在画布中的坐标点 */
/* 此处注意:text.width获得文字的宽度,然后就能计算出文字居中需要的x值 */
ctx.fillText(insertContent, (width - measureText.width) / 2, (height / 2) + 45);/* 填充百分比 */
ctx.font = '60px Microsoft YaHei';
ctx.fillStyle = '#222';const ratioStr = `${(parseFloat(percent) * 100).toFixed(0)} %`;
const text = ctx.measureText(ratioStr);
ctx.fillText(ratioStr, (width - text.width) / 2, (height / 2) + 10);/* 开始圆环 */
const circleConfig = {/* 圆心坐标 */x: width / 2,y: height / 2,/* 半径,下方出现的150都是半径 */radius: (width / 2) - 30,/* 环的宽度 */lineWidth: 24,/* 开始的度数-从上一个结束的位置开始 */startAngle: 0, // 注意这里的0是3点钟方向,而非12点方向,和数学里的不一样/* 结束的度数 */endAngle: 360,color: '#E7EFF4',
};/* 灰色的圆环 */
drawCircle(ctx, circleConfig);/* 有色的圆环 */
const holeCicle = 2 * Math.PI;
const angle = percent * 360; // 圆弧的角度// 圆心坐标:(x0, y0)
// 半径:r
// 弧度:a   => 圆弧计算公式:(角度/180)*Math/.PI
// 则圆上任一点为:(x1, y1)
// x1 = x0 + r * cos(a)
// y1 = y0 + r * sin(a)
const x1 = circleConfig.x + circleConfig.radius * Math.cos(((angle - 90) / 180) * Math.PI) - 25;
const y1 = circleConfig.y + circleConfig.radius * Math.sin(((angle - 90) / 180) * Math.PI) - 25;// 处理渐变色
const gnt1 = ctx.createLinearGradient(circleConfig.radius * 2, circleConfig.radius * 2, 0, 0);
gnt1.addColorStop(0, '#FF8941');
gnt1.addColorStop(0.3, '#FF8935');
gnt1.addColorStop(1, '#FFC255');drawCircle(ctx, {...circleConfig,/* 从-90度的地方开始画 */startAngle: -0.5 * Math.PI, // 把起始点改成数学里的12点方向endAngle: -0.5 * Math.PI + percent * holeCicle,color: gnt1,
});// 填充小图标
if (isIconLoadSuccess) {// 这里的this指的是imgObj,第二三个参数是它的坐标,四五个是长款ctx.drawImage(iconLoading, x1, y1, 50, 50);
}
  1. 来一点动画

方法名称:drawFrame(percent, callback)

// 在该方法之外声明一个全局变量
let speed = 0;
// 以下是 drawFrame 方法体
const id = window.requestAnimationFrame(() => { drawFrame(percent, callback); });
circle(speed.toString());
if (speed >= percent) {window.cancelAnimationFrame(id);speed = 0;if (callback) {callback();}return;
}
speed += 0.01;
  1. 再来一个快照功能

方法名称:createImage(src)

const image = new Image();
image.src = src;
return image;
  1. 调用声明好的方法
const app = document.getElementById('app');
const canvas = createCanvas();let i = 0;
setInterval(() => {if (i > 1) {i = 0;}i = Math.random();drawFrame(i.toString(), () => {const image = createImage(canvas.toDataURL());app.appendChild(image);window.scrollTo(0, document.body.scrollHeight);});
}, 3000);app.appendChild(canvas);

完整代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>进度条圆环</title><style>body {width: 100%;height: 100vh;overflow-y: auto;overflow-x: hidden;}</style>
</head><body><div id="app"></div>
</body><script>// 图标是否加载成功let isIconLoadSuccess = false;let iconLoading = null;function createCanvas() {const canvas = document.createElement('canvas');canvas.width = 300;canvas.height = 300;canvas.style.border = '1px #ccc solid';// 提前加载图标数据const imgObj = new Image();imgObj.src = './success-filling.png';imgObj.onload = function () {isIconLoadSuccess = true;iconLoading = this;};return canvas;}const app = document.getElementById('app');const canvas = createCanvas();/* 画曲线 */function drawCircle(ctx, config) {const {x, y, radius, startAngle, endAngle, color, lineWidth,} = config;ctx.beginPath();ctx.arc(x, y, radius, startAngle, endAngle, false);// 设定曲线粗细度ctx.lineWidth = lineWidth;// 给曲线着色ctx.strokeStyle = color;// 连接处样式ctx.lineCap = 'round';// 给环着色ctx.stroke();ctx.closePath();}function circle(percent = '0.0') {const { width, height } = canvas;const ctx = canvas.getContext('2d');// 清除画布ctx.clearRect(0, 0, width, height);// 保存ctx.save();/* 填充文字 */ctx.font = '24px Microsoft YaHei';/* 文字颜色 */ctx.fillStyle = '#999';/* 文字内容 */const insertContent = '本月任务进度';// 拿到文本内容的像素相关信息 单位长度(px)const measureText = ctx.measureText(insertContent);/* 插入文字,后面两个参数为文字在画布中的坐标点 *//* 此处注意:text.width获得文字的宽度,然后就能计算出文字居中需要的x值 */ctx.fillText(insertContent, (width - measureText.width) / 2, (height / 2) + 45);/* 填充百分比 */ctx.font = '60px Microsoft YaHei';ctx.fillStyle = '#222';const ratioStr = `${(parseFloat(percent) * 100).toFixed(0)} %`;const text = ctx.measureText(ratioStr);ctx.fillText(ratioStr, (width - text.width) / 2, (height / 2) + 10);/* 开始圆环 */const circleConfig = {/* 圆心坐标 */x: width / 2,y: height / 2,/* 半径,下方出现的150都是半径 */radius: (width / 2) - 30,/* 环的宽度 */lineWidth: 24,/* 开始的度数-从上一个结束的位置开始 */startAngle: 0, // 注意这里的0是3点钟方向,而非12点方向,和数学里的不一样/* 结束的度数 */endAngle: 360,color: '#E7EFF4',};/* 灰色的圆环 */drawCircle(ctx, circleConfig);/* 有色的圆环 */const holeCicle = 2 * Math.PI;const angle = percent * 360; // 圆弧的角度// 圆心坐标:(x0, y0)// 半径:r// 弧度:a   => 圆弧计算公式:(角度/180)*Math/.PI// 则圆上任一点为:(x1, y1)// x1 = x0 + r * cos(a)// y1 = y0 + r * sin(a)const x1 = circleConfig.x + circleConfig.radius * Math.cos(((angle - 90) / 180) * Math.PI) - 25;const y1 = circleConfig.y + circleConfig.radius * Math.sin(((angle - 90) / 180) * Math.PI) - 25;// 处理渐变色const gnt1 = ctx.createLinearGradient(circleConfig.radius * 2, circleConfig.radius * 2, 0, 0);gnt1.addColorStop(0, '#FF8941');gnt1.addColorStop(0.3, '#FF8935');gnt1.addColorStop(1, '#FFC255');drawCircle(ctx, {...circleConfig,/* 从-90度的地方开始画 */startAngle: -0.5 * Math.PI, // 把起始点改成数学里的12点方向endAngle: -0.5 * Math.PI + percent * holeCicle,color: gnt1,});// 填充小图标if (isIconLoadSuccess) {// 这里的this指的是imgObj,第二三个参数是它的坐标,四五个是长款ctx.drawImage(iconLoading, x1, y1, 50, 50);}}function createImage(src) {const image = new Image();image.src = src;return image;}// 动画函数let speed = 0;function drawFrame(percent, callback) {const id = window.requestAnimationFrame(() => { drawFrame(percent, callback); });circle(speed.toString());if (speed >= percent) {window.cancelAnimationFrame(id);speed = 0;if (callback) {callback();}return;}speed += 0.01;}let i = 0;setInterval(() => {if (i > 1) {i = 0;}i = Math.random();drawFrame(i.toString(), () => {const image = createImage(canvas.toDataURL());app.appendChild(image);window.scrollTo(0, document.body.scrollHeight);});}, 3000);app.appendChild(canvas);
</script></html>

使用到的小图标

最终效果图

使用canvas绘制圆环进度条相关推荐

  1. android绘制环形进度_Android使用Canvas绘制圆形进度条效果

    前言 Android自定义控件经常会用到Canvas绘制2D图形,在优化自己自定义控件技能之前,必须熟练掌握Canvas绘图机制.本文从以下三个方面对Canvas绘图机制进行讲解: 画布Canvas ...

  2. 使用canvas绘制圆形进度条

    实现步骤: 绘制一个圆: 绘制圆环: 绘制进度环: 绘制文字: 一.创建画布 <canvas id='myCanvas' width='200' height='200'></can ...

  3. SVG绘制圆环进度条

    在我们的大屏可视化项目中,经常会用到各种各样的图表.与传统的表格展示.枯燥的文字阐述相比,图表展示则使用户看起来更加直观.数据的展示则更加一目了然.本文基于svg绘图技术结合前端技术栈vue,以工作中 ...

  4. canvas 绘制圆形进度条

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...

  5. 使用h5 canvas绘制圆形进度条

    创建一个Html容器canvas: <canvas id="myCanvasTag" width="300" height="300" ...

  6. H5 Canvas绘制圆形进度条动画效果

    效果如图 效果比较简单 html结构部分 <canvas id="canvas" width="110" height="110"&g ...

  7. android制作扇形进度条,canvas绘制扇形进度条

    您的浏览器版本太老,不支持canvas,建议升级浏览器 24小时 您的浏览器版本太老,不支持canvas,建议升级浏览器 30分 function drawBingTu(canvasid,canvas ...

  8. uni-app中自定义图表(canvas实现chart图表)开发篇(5)-圆环进度条添加动画效果

    这里增加一篇介绍下进度条动画效果如何添加,前几篇的进度值被修改后,切换效果比较生硬.另外也在第四篇基础上,对图形略作修改.在查看uniapp文档时,没有发现重绘执行函数,小程序中有Canvas.req ...

  9. java如何画百分比圆环_canvas绘制百分比圆环进度条

    开发项目,PM会跟踪项目进度:完成某个事情,也可以设置一个完成的进度. 这里用canvas绘制一个简单百分比圆环进度条. 看下效果: 1. 动画方式 2. 静默方式 贴上代码,仅供参考 /** * L ...

最新文章

  1. Visual Studio 2008 Samples Page
  2. 用Perl发送邮件小例子
  3. 网站增改不要只想着收益更应该思考原有的损失
  4. 【LDA学习系列】MCMC之Metropolis-Hastings采样算法python代码理解
  5. 一张图弄懂opengl的诸多库gl glu glut freeglut glew glfw之间关系
  6. 把数据保存到cook_JavaScript数据存储 Cookie篇
  7. vue 数组数据改变 视图不更新解决方案
  8. IWMS实现频道页面的方法
  9. html绘制城堡,网页上的虚幻3,HTML5版《史诗城堡》体验
  10. Unity3D引用dll打包发布的问题及解决
  11. UltraEdit键盘快捷键
  12. web of science上查找相关会议和期刊的论文
  13. 阿里矢量库图标在线链接的使用方法,引入,改变大小与颜色
  14. 玩客云服务器怎么卖,玩客云使用教程;低价NAS怎么打造;玩客云现在还值得入手吗?-聚超值...
  15. 进程的守护神 - daemontools(进程监控)
  16. Forth 系统实现
  17. onblur onchange
  18. Mathematica(26)-在软件中插入图片
  19. java 人脸检测 人脸抓拍
  20. SpringBoot2.x(三)热部署devtool和配置文件自动注入实战

热门文章

  1. Materials Studio建模——异质结的建立(2)
  2. 绘制STM32最小系统电路原理图、STM32F103读取SD卡的数据
  3. 无人驾驶11:行为规划
  4. 计算机考研2018大纲,2018计算机考研大纲原文.pdf
  5. 2000-2018年融资约束SA指数计算命令和数据
  6. python实现测试android应用冷启动
  7. 如何让键盘支持自动输入
  8. 2015年12月英语总结
  9. javaweb记账本系统
  10. 苹果4s怎么显示无服务器,苹果4s连接电脑没有反应怎么办 苹果4s怎么连接电脑...