# canvas甜甜圈動畫效果的實現
> 前段時間,公司的老板說要個高大上的計算器,類似支付包的記賬的特效。看到這個效果后,就想到了canvas實現是最好的。
>
* 主要用到的函數也就是arc函數 這部可以參考之前寫的文章 [arc函數](http://www.hmoore.net/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下的配置
- 微信公眾號開發
- 測試號配置