温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

canvas怎么实现环形进度条效果

发布时间:2021-05-12 13:58:35 来源:亿速云 阅读:307 作者:小新 栏目:web开发

这篇文章将为大家详细讲解有关canvas怎么实现环形进度条效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

canvas怎么实现环形进度条效果

这里就选canvas来简单写一下 先上代码,然后在说一说需要注意的点:

<!DOCTYPE html> <html> <head>  <meta charset="utf-8">  <title>canvas环形进度条</title>  <style>  body{  background-color:#000;  text-align: center;  }  .canvas1{  margin-top: 100px;  display: inline-block;  background-color: #FFF;  }  </style> </head> <body>  <canvas id="circle_process" class="canvas1"></canvas>  <script>  /*  需求:环形、一周分为10个片段,根据进度去走的一个状态  技术选型:canvas (挑战加熟悉)  思路:  01 首先中间的文字部分不用说,使用canvas的画文字。  02 圆形是个规则图形,那么为了避免画不规则图形,我们可以用圆和矩形来重叠出效果。  a. 大的灰色背景圆  b. 小一圈的白色背景圆  c. 以同心圆的圆心为圆心,小圆为半径为半径复制画10个小的矩形  */  //初始化动画变量  var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;  var cancelAnimationFrame = window.cancelAnimationFrame || window.msCancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelRequestAnimationFrame;  //初始化当前进度数  var curPercentCount = 0;  //获取canvas对象,设置画布大小  var oC = document.querySelector('#circle_process');  oC.width = 300;  oC.height = 300;  //获取canvas执行上下文  var ctx = oC.getContext('2d');  //定义小矩形的个数  var miniRectCount = 10;  //定义圆心位置  var cirCenter = {  x:oC.width/2,  y:oC.height/2  };  //定义小矩形的大小rectSize  var rectSize = {  width:0,  height:0  };  //圆对象构造函数  function Circle(center,radius){  this.center = center;  this.radius = radius;  }  //小矩形对象构造函数  function MiniRect(length,width){  this.length = length;  this.width = width;  }  //角度转换成弧度的函数  function d2a(angleInt){  return angleInt*Math.PI / 180;  }  //百分比转换角度函数(这里减90因为arc0度是从右侧开始的)  function percentTurn(percentFloat){  return percentFloat * 360 / 100 - 90;  }  //画当前百分比扇形的方法  function drawFanForPercent(percentFloat){  ctx.beginPath();  ctx.moveTo(cirCenter.x,cirCenter.y);  ctx.lineTo(oC.width/2,(oC.height-baseCircle.radius*2)/2);  ctx.arc(cirCenter.x,cirCenter.y,baseCircle.radius,d2a(-90),d2a(percentTurn(percentFloat)));  ctx.fillStyle = 'aqua';  ctx.fill();  ctx.closePath();  }  //画圆的函数  function drawArc(center,radius,start,end,type,color){  start = start || 0;  end = end || 360;  ctx.beginPath();  ctx.arc(center.x,center.y,radius,d2a(start),d2a(end));  ctx.fillStyle = color;  ctx.strokeStyle = color;  if(!!type){  (type === 'fill') && ctx.fill();  (type === 'stroke') && ctx.stroke();  }  ctx.closePath();  }  //画文字的函数  function drawPercentText(text,percentInt){  ctx.beginPath();  ctx.fillStyle = 'aqua';  ctx.font="italic small-caps bold 40px Calibri";  ctx.textAlign = 'center';  ctx.fillText(text,cirCenter.x,cirCenter.y-18,100);  ctx.closePath();  ctx.beginPath();  ctx.fillStyle = 'aqua';  ctx.font="italic small-caps bold 60px Calibri";  ctx.textAlign = 'center';  ctx.fillText(percentInt+'%',cirCenter.x,cirCenter.y+40,100);  ctx.closePath();  }  //画小方块的方法  function drawMiniRect(startPoint,width,height,axisPoint,rotateAngle){  /*  ctx.beginPath();  //平移,画出第一个  ctx.save();  ctx.translate(startPoint.x,startPoint.y);  ctx.fillStyle = '#FFF';  ctx.fillRect(0,0,rectSize.width,rectSize.height);  ctx.restore();  ctx.closePath();  //这种先平移画出在旋转的思路是错的,画之后就不能转了  ctx.save();  ctx.translate(axisPoint.x,axisPoint.y);  ctx.rotate(rotateAngle);  ctx.restore();  */  ctx.save();  ctx.translate(axisPoint.x,axisPoint.y); /*画布平移到圆的中心*/  ctx.rotate(d2a(rotateAngle)); /*旋转*/  /*画*/  ctx.beginPath();  ctx.fillStyle = '#FFF';  ctx.fillRect(startPoint.x,startPoint.y,rectSize.width,rectSize.height);  ctx.closePath();  ctx.restore();  }  //画整体  function draw(curPercent){  //底部灰色圆  drawArc(baseCircle.center,baseCircle.radius,null,null,'fill','#CCC');  //进度扇形  drawFanForPercent(curPercent);  //内部白色遮挡圆  drawArc(innerCircle.center,innerCircle.radius,null,null,'fill','#FFF');  //画文字  drawPercentText('当前进度',curPercent);  //十个小的矩形  for(var i=0; i<miniRectCount; i++){  drawMiniRect(startPoint,rectSize.width,rectSize.height,cirCenter,i*360/miniRectCount);  }  }  //实例化底圆和内圆  var baseCircle = new Circle(cirCenter,130);  var innerCircle = new Circle(cirCenter,100);  //设置rectSize数值  rectSize.width = 15;  rectSize.height = baseCircle.radius - innerCircle.radius + 5;  //设置第一个小矩形的起始点 (这里有误差)  // var startPoint = {  // x: oC.width /2 - 7.5,  // y: (oC.height - baseCircle.radius*2) / 2  // };  //由于平移到中心点之后画的位置是在画布外的,所以重新定义  var startPoint = {  x:-7.5,  y:-baseCircle.radius - 2  };  //这里开定时去显示当前是百分之几的进度  var raf = null;  var percent = 0;  function actProcess(percentFloat){  percentFloat = percentFloat || 100;  percent = Math.round(percentFloat);  console.log(percent);  curPercentCount++;  raf = requestAnimationFrame(function(){  actProcess(percentFloat);  });  draw(curPercentCount);  if(curPercentCount >= percent){  cancelAnimationFrame(raf);  return;  }  }  actProcess(50);  // cancelAnimationFrame(raf);  //这里没搞懂为什么percent会加 ?  //解: requestAnimationFrame中方法还是需要有参数,这里就用匿名函数回调的执行体去指定。  /*  //setInterval的方式  function actProcess(percentFloat){  if(curPercentCount >= percentFloat){  clearInterval(timer);  return;  }  curPercentCount++;  draw(curPercentCount);  }  clearInterval(timer);  var timer = setInterval(function(){  actProcess(50);  },16.7);  */   //直接画弧形的测试:  //drawArc(innerCircle.center,innerCircle.radius,0,260,'fill','red');  /*  用到的技术点:  01 canvas平移  02 canvas画布状态保存于恢复  03 canvas旋转  04 canvas clearRect配合动画requestAnimationFrame  05 canvas写文字  */  </script> </body> </html>

接下来说一些注意点和我写的过程中碰到的疑问:

疑问:

01 整体代码没有封装成一个组件,感兴趣的同学可以封装一下。 我这有时间也会封装。

02 画文字的时候只能单独画一行文字么? 怎样进行换行?

03 canvas怎样处理响应式?

注意点:

01 画布平移之后,画布上的点也会被平移,所以我在定义第一个小矩形的起始点的时候才会重新定义一个负值。

02 直接画弧形来控制进度不准确,因为arc会自动closePath(),最终形成这样的一个效果。

canvas怎么实现环形进度条效果

03 默认圆的0度起始位置是从3点钟方向开始的(见上图),那么想从12点钟位置开始走进度,需要减去90度的角度。

04 requestAnimationFrame的回调函数在有参数的情况下还是需要传参数的,需要借助匿名函数回调,在执行体里面去执行想要loop的函数内容(可传参数)。否者会出现注释中写道的pecent不规则增加的问题。

先就这样,之后可能会结合一个上传图片的小功能尝试把它封装成一个组件。

关于“canvas怎么实现环形进度条效果”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI