摘要:使用繪制的可交互扇形現有動畫實現方式的不足和都不十分精確。為它們傳入的第二個參數,實際上只是指定了把動畫代碼添加到瀏覽器線程隊列中以等待執行的時間。就是為了繪制而生,再合適不過了。感興趣的看官點擊這里本文轉載自筆者的個人博客
使用H5 canvas繪制的可交互扇形
requestAnimationFrame()現有動畫實現方式的不足
setTimeout和setInterval都不十分精確。為它們傳入的第二個參數,實際上只是指定了把動畫代碼添加到瀏覽器UI線程隊列中以等待執行的時間。如果隊列前面已經加入了其他任務,那動畫代碼就要等前面的任務完成后再執行。
css3動畫有局限性,比如不是所有屬性都能參與動畫、動畫緩動效果太少、無法完全控制動畫過程等。
requestAnimationFrame()的優勢
它告訴瀏覽器某些JavaScript代碼將要執行動畫,瀏覽器可以再運行某些代碼后進行適當的優化,十分精確,沒有css3的局限問題,可對所有屬性操作,動畫緩動效果可以依據緩動公式,十分豐富。
requestAnimationFrame()就是為了繪制canvas而生,再合適不過了。
代碼實現
var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; function updateProgress() { var div = document.getElementById("status"); div.style.width = (parseInt(div.style.width, 10) + 5) + "%"; if(div.style.left != "100%") { requestAnimationFrame(uploadProgress); } } requestAnimationFrame(uploadProgress);
這里展示高級瀏覽器版本,兼容版請自行google。
easing緩沖動畫當初學習的時候的文章找不到了,大致的理解是:時間間隔一直,每個間隔運行的距離不同。
//iteration當前執行次數 //startValue執行開始的位置 //changeValue需要執行到的最終位置 //totalIterations需要執行的總次數 easing.easeOutBounce(iteration, startValue, changeValue, totalIterations);
看上面的參數能了解到,easing產生的是與直線的偏移,iteration表示的是偏移的延續,totalIterations表示的動畫進行速度,startValue表示的是偏移的起始,changeValue表示的是偏移的量。
canvas方法用到的一些canvas方法:
fillRect():在畫布上繪制的矩形會填充指定顏色,由fillStyle屬性指定
strokeRect():在畫布上繪制的矩形會使用指定的顏色描邊,由strokeStyle屬性指定
clearRect():清除畫布上的矩形區域
arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)為圓心繪制一條弧線,弧線半徑為radius,起始和結束角度(用弧度表示)分別為startAngle和endAngle。最后一個參數表示是否按逆時針方向計算,值為false表示順時針方向計算
lineTo(x, y):從上一點開始繪制一條直線,到(x, y)為止
drawImage(image, x, y, width, height):繪制圖像到畫布上,參數有3種,不一一介紹
save()與restore():保存上下文環境,操作...,恢復上次保存的上下文環境
這里只用到了這些,其他方法以后再介紹
css3 3D Transform為了能更酷炫點,再加上css3的3D翻轉效果
transform-style:指定嵌套元素如何在3D空間中呈現。它主要有兩個屬性值:flat和preserve-3d,它本身需要設置在父元素中,如果設置了transform-style值為preserve-3d,就不能設置overflow值為hidden
perspective:設置查看者的位置,并將可視內容映射到一個視錐上,繼而投到一個2D視平面上,就是視距
perspective-origin:決定perspective屬性的源點角度
transition:過渡效果
translateZ():使一個元素在三維空間移動
rotateY():指定一個元素圍繞Y軸旋轉,旋轉的量被定義為指定的角度;如果值為正值,元素圍繞Y軸順時針旋轉;反之,如果值為負值,元素圍繞Y軸逆時針旋轉
這里只用到了這些,不做詳細介紹,太多了...
準備工作先進行到這里,接下來進行本例的講解。
具體實現參數數組
value:所占比重,百分之幾
color:選中時顏色
highlight:選中時鼠標懸停時顏色
grey:未選中時顏色
greylight:未選中時鼠標懸停時顏色
我自己設置傳入的參數:
var pieData = [ { value: 0.32, color:"#E8264b", highlight: "#FF0049", grey: "#5B5B5B", greylight: "#333" }, { value: 0.13, color: "#E64261", highlight: "#FF5A5E", grey: "#666", greylight: "#333" }, { value: 0.13, color: "#E05070", highlight: "#FF5A5E", grey: "#727272", greylight: "#444" }, { value: 0.1, color: "#E05D7D", highlight: "#FF5A5E", grey: "#7F7F7F", greylight: "#444" }, { value: 0.09, color: "#DB7691", highlight: "#FF5A5E", grey: "#8E8E8E", greylight: "#666" }, { value: 0.09, color: "#D6829C", highlight: "#FF5A5E", grey: "#999", greylight: "#666" }, { value: 0.07, color: "#D497AA", highlight: "#FF5A5E", grey: "#A5A5A5", greylight: "#666" }, { value: 0.07, color: "#D497AA", highlight: "#FF5A5E", grey: "#A5A5A5", greylight: "#666" } ];
繪制圓盤
function drawing (ctx, i) {//傳入canvas的context startValue = endValue;//每個扇形開始繪制的位置 endValue = startValue + Math.PI * pieData[i].value * 2;//每個扇形結束繪制的位置 ctx.beginPath();//開始繪制 ctx.arc(225, 225, radiusBig, startValue, endValue, false);//繪制扇形的弧線 ctx.lineTo(225,225);//繪制扇形鏈接圓心的兩條直線 ctx.lineWidth = 2;//設置線的寬度 ctx.closePath();//結束繪制 ctx.fillStyle = pieData[i].grey;//設置扇形顏色 ctx.strokeStyle = "#fff";//設置線的顏色 ctx.fill();//填充 ctx.stroke();//描邊 }
繪制文字及其位置
putIcon()用來計算繪制位置,r為半徑,θ為角度,x = r + r sinθ, y = r - r cosθ,left和top的值為x和y。
(先寫在這,本人不會畫圖,等學會再來畫)
function drawThing(ctx) { var i = 0; var icon = undefined; for( ; i < pieLen ; i++ ) { drawing(ctx, i); } for(i = 0 ; i < pieLen ; i++ ) { if( !effects[i].clicked ) { icon = putIcon(i, 225, 140); ctx.font = "bold 30px Arial"; ctx.textAlign = "center"; ctx.fillStyle = "#fff"; ctx.fillText(i + 1, icon.x, icon.y); } } } function putIcon(count, radiusW, radiusN) { var values = angle = i = 0; for( ; i < count; i++) { values += pieData[i].value; } angle = Math.PI * 2 * (values + pieData[count].value / 2); return { x: Math.floor(radiusW + Math.sin(angle) * radiusN), y: Math.floor(radiusW - Math.cos(angle) * radiusN) } }
確定交互區域
確定交互區域本人的思路是獲取鼠標在視口上的(x ,y),再將這個點是否是可交互區域,能耗可能會比較大,沒想到更好的做法,不過看到css3的clip-path屬性可以實現類似效果,之后會研究下。
首先確定點擊區域為外層大圓與內層小圓之間,公式:(x - r) (x - r) + (y - r) (y - r) = r * r;
直線方程:(x - x1)/(x2 - x1) = (y - y1)/(y2 - y1);
兩點即可判斷一條直線,先確定圓心點(r, r),再根據角度確定直線與圓交點(r + r sinθ, y = r - r cosθ)
得到的直線方程為:y = (x - r) (-r cosθ) / (r * sinθ) + r;
相鄰兩條直線建立二元一次不等式組,即可確定中間區域;
動畫緩動
將easing與requestAnimationFrame()的結合使用,這是實現掉落效果的動畫
function clickThing (ctx, i) { var iteration = 0; var totalIterations = 30; var backX, backY; var icon = putIcon(i, 225, 140, true); var ty = icon.y - 25; //立即執行的遞歸方法 (function miniIcon () { ctx.clearRect(0, 0, 500, 500); backY = easing.easeOutBounce(iteration, ty, 25, totalIterations); ctx.font = "bold 30px Arial"; ctx.textAlign = "center"; ctx.fillStyle = "#fff"; ctx.fillText(i + 1, icon.x, backY); if(iteration < totalIterations) { iteration++; requestAnimationFrame(function () { miniIcon(); }); } })(); }
使用css3實現3D翻轉效果
最外層設置視距perspective: 2000px;perspective-origin:right top;
父級設置transition: all 0.7s ease-out;transform-style: preserve-3d;子級設置left和top為自身高寬的一半,使圓心位置為翻轉中心點,back-c為背面,front-c為正面,改變rotatey(0deg)為rotatey(-180deg)表示從正面翻轉180度到背面,反之亦然,translateZ()在這里用來表示層疊關系,一層蓋在另一層上面。
.wrap { perspective: 2000px; perspective-origin:right top; position: relative; width: 450px; height: 450px; } .wrap .wrap-box { transition: all 0.7s ease-out; transform-style: preserve-3d; position: absolute; top: 50%; left: 50%; } #back-c { position: absolute; top: -225px; left: -225px; transform: translateZ(1px) rotatey(0deg); } #white-c { position: absolute; top: -225px; left: -225px; transform: translateZ(-2px) rotatey(0deg); } #front-c { position: absolute; top: -225px; left: -225px; transform: translateZ(-1px) rotatey(-180deg); }
html內容
寫了很多canvas,white-c是翻轉之后蓋在上面的白色小圓,每次繪制都要畫一次,所以拿出來減少能耗,text-c也是出于這個原因,text-c用來繪制小動畫,line-c是拿出來當觸發器用的,沒必要單拎出來,只是想區分用途才拿出來的。
總結
花了點時間看了下自己的代碼,找尋下迷失的自己,繼續啟程。
感興趣的看官點擊這里:coding:circle
本文轉載自筆者的個人博客:Gaoxuefeng"s Blog
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79402.html
摘要:最近在做一些活動的需求,發現用到轉盤的機會很大。轉盤的旋轉控制首先,能夠在點擊轉的按鈕時候做一些判斷是否可以開轉,使用變量來控制。最近在做一些h5活動的需求,發現用到轉盤的機會很大。 代碼已經開源,感興趣的同學可查看react-turnplate 先上效果 showImg(https://user-gold-cdn.xitu.io/2019/5/18/16ac949855bdd316); ...
摘要:扇形制作原理,底部一個純色原形,里面個相同顏色的半圓,可以是白色內部半圓按一定角度變化,就可以產生出扇形效果扇形繪制這個屬性用來繪制半圓,在的范圍內的內容顯示出來,使用屬性,元素必須是的繪制一個度扇形繪制一個度扇形 扇形制作原理,底部一個純色原形,里面2個相同顏色的半圓,可以是白色,內部半圓按一定角度變化,就可以產生出扇形效果 扇形繪制 .shanxin...
摘要:扇形制作原理,底部一個純色原形,里面個相同顏色的半圓,可以是白色內部半圓按一定角度變化,就可以產生出扇形效果扇形繪制這個屬性用來繪制半圓,在的范圍內的內容顯示出來,使用屬性,元素必須是的繪制一個度扇形繪制一個度扇形 扇形制作原理,底部一個純色原形,里面2個相同顏色的半圓,可以是白色,內部半圓按一定角度變化,就可以產生出扇形效果 扇形繪制 .shanxin...
閱讀 2741·2021-11-24 09:39
閱讀 1650·2021-09-28 09:35
閱讀 1123·2021-09-06 15:02
閱讀 1315·2021-07-25 21:37
閱讀 2731·2019-08-30 15:53
閱讀 3649·2019-08-30 14:07
閱讀 719·2019-08-30 11:07
閱讀 3518·2019-08-29 18:36