ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# canvas甜甜圈动画效果的实现 > 前段时间,公司的老板说要个高大上的计算器,类似支付包的记账的特效。看到这个效果后,就想到了canvas实现是最好的。 > * 主要用到的函数也就是arc函数 这部可以参考之前写的文章 [arc函数](https://www.kancloud.cn/kingend/js-work/472267) * 实现的核心其实是增量,就是上次结束的弧度成为下次弧度的开始,便可以平滑过度。 * 关于动画,有个实现原理,就是一秒最少要20fps。(fps是帧) 一言不合贴的代码: ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>甜甜圈</title> <style> * { margin: 0; padding: 0; } </style> </head> <body> <canvas id="pan"></canvas> </body> <script> // 初始化函数 var pan = document.getElementById('pan') var width = window.outerWidth var height = window.outerHeight pan.width = width pan.height = height //绘画状态 let opts = { "start": Math.PI * 1.5, "end" : Math.PI * 3, "color": "red" } /** * 绘画圆弧 * @param options 配置文件 */ function drawPie (opts) { /** * @param startAngle 开始弧度 * @param endAngle 结束弧度 * @param timeAngle 每次绘制的弧度的增量 * @param sumAngle 总的绘制的弧度 * @param initStartAngle 一开始弧度和总增量的和 用于判断是否绘画完成 * @param vDraw 绘制的速度 50ms */ var startAngle = opts.start, endAngle = opts.end, timeAngle, sumAngle, initStartAngle, vDraw = 50; sumAngle = startAngle - endAngle if (sumAngle<0) { sumAngle = -sumAngle } initStartAngle = opts.start + sumAngle timeAngle = (sumAngle / 1000) * vDraw var ctx = pan.getContext("2d") // 弧度 = 角度 * Math.PI / 180 var timerHandle = setInterval(function () { /** * 应该获取到上次的结束的弧度,作为下次开始的弧度 **/ ctx.arc(width / 2, height /2, 50, opts.start, opts.start + timeAngle, false ) ctx.strokeStyle=opts.color ctx.lineWidth= 40 ctx.stroke() // 判断是否绘画到需要的点 if(initStartAngle >= opts.start + timeAngle) { opts.start = opts.start + timeAngle } else { console.log('end') clearInterval(timerHandle) } }, vDraw) } drawPie(opts) </script> </html> ~~~ 后记: 这个只是个简单的demo,线条的优化等,还有定时函数的替代函数requestAnimationFrame,毕竟js是单线程,同时使用两个高触发的定时函数,是很危险的事情,一不小心就会照成浏览器卡顿。也可以使用worker技术,开启多线程。不过我也没有用worker技术 参考资料: [js封装缓动动画](http://blog.csdn.net/qq_18972075/article/details/50018339) [知乎回答js平滑动画效果的实现](https://www.zhihu.com/question/20453427)