# 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)
- 前端
- pc端
- 京东无延时菜单效果
- datapicker组件的编写
- cursor禁止默认样式
- 移动端
- web在真机调试
- 有关vue的上拉加载
- 下拉刷新
- vue获取dom节点
- worker技术
- h5页面唤醒手机拨号,发短信功能
- 弹出层唤醒挤压css背景图片
- 23模式
- 基础模式
- SMD同步模块
- canvas
- 点的均匀分布
- 线条绘画
- canvas常见的全局属性
- 判断点在某个区间内
- 保证动画效果的流畅性
- arc函数学习
- cookies
- 本地服务搭建
- Mint UI框架的学习
- 第一天
- Swiper组件的解析
- loadmore组件
- 二维码的生成
- 前端优化
- 浏览器缓存
- indexdb本地数据库的使用
- 浅谈前端优化
- css渐变属性
- 前端常用组件学习
- picker组件
- vue
- 模块下的state访问
- vue的进阶
- npm包的发布
- 淘宝移动端适配问题
- vue的生命周期的理解
- vue的路由学习
- vue自带的动画效果
- vue 项目里,img标签报错,添加默认图片
- axios 实现loading加载提示
- qs库
- vue的v-for指令无法使用在tr、td中
- vue打包之后,npm run dev 空白
- vue 单页面百度统计
- unix时间转化
- UI组件的实现
- picker
- upload组件
- js动画效果
- canvas甜甜圈的编写
- 瀑布流实现
- 适配问题
- 图片加载
- js基础知识
- js数组合并
- 响应布局总结
- 组件开发
- grid组件
- 专题页面常用布局页面
- scroll滚动问题
- 项目整理经验收集
- 画图工具应用实现记录
- 参考线实现
- JCode
- 多条件筛选不用ajax的原因分析
- node
- koa路由下的分块
- 连接数据库mysql
- 初步搭建数据库模型
- java
- spring框架的学习
- maven 搭建web项目
- 建站
- 关联github
- 杂文
- 后端常用成熟系统
- node实战练习
- 编写邮箱通知
- 微信小程序
- 模板之坑
- 模板坑之数据传入
- 小程序组件化之一
- 有关this的绑定
- 小程序组件化之二
- 小程序分包加载
- tab切换,页面状态不更新
- 小程序请求组件(草稿)
- php学习之路
- 文件上传
- 有关数据库时间类型的插入
- Ubuntu下的php开启扩展模块
- windows系统下的hosts文件位置
- 腾讯云的cos
- thinkPHP
- 模块设计
- 模型的使用
- ajax的请求异常总结
- apache服务器
- 虚拟主机的建立
- ssh的使用
- ftp服务器配置
- Lamp的搭建
- ftp从零开始配置
- https的配置
- git hooks实现简单的自动部署
- ubuntu系统登录远程ubuntu服务器
- ubuntu
- 新建用户需要使用sudo
- sftp的文件上传问题
- 配置apache部分问题总结
- git服务器的搭建
- githook的学习
- ubuntu 虚拟主机搭建
- ubunut的服务器的防火墙的关闭
- 宝塔部署laravel
- 关于宝塔phpmyadmin无法访问的问题
- 解决码云每次提交输入密码的问题
- mysql
- phpmyadmin的安装
- 远程登陆数据库
- git的使用
- 拉去分支的代码
- git remote指令
- 学习临时笔记
- ios兼容性问题
- 苹果获取屏幕宽度问题
- toDataURL无法导出图片
- 苹果触屏滚动,下拉刷新问题
- jquery动画
- jquery的animate无法使用transform
- jquery队列queue
- css重学之路
- 规范一
- css3的matrix属性
- 淘宝适配方案
- Yii框架学习
- gd库的支持安装
- larval框架学习
- 中间件
- 指令
- 自定义指令生成token
- 微信登录后端篇
- 宝塔apache配置ssl
- SVN
- PS
- 快捷键
- Redis
- Redis在Unbtun下的配置
- 微信公众号开发
- 测试号配置