摘要:使用繪制的可交互扇形現(xiàn)有動(dòng)畫(huà)實(shí)現(xiàn)方式的不足和都不十分精確。為它們傳入的第二個(gè)參數(shù),實(shí)際上只是指定了把動(dòng)畫(huà)代碼添加到瀏覽器線(xiàn)程隊(duì)列中以等待執(zhí)行的時(shí)間。就是為了繪制而生,再合適不過(guò)了。感興趣的看官點(diǎn)擊這里本文轉(zhuǎn)載自筆者的個(gè)人博客
使用H5 canvas繪制的可交互扇形
requestAnimationFrame()現(xiàn)有動(dòng)畫(huà)實(shí)現(xiàn)方式的不足
setTimeout和setInterval都不十分精確。為它們傳入的第二個(gè)參數(shù),實(shí)際上只是指定了把動(dòng)畫(huà)代碼添加到瀏覽器UI線(xiàn)程隊(duì)列中以等待執(zhí)行的時(shí)間。如果隊(duì)列前面已經(jīng)加入了其他任務(wù),那動(dòng)畫(huà)代碼就要等前面的任務(wù)完成后再執(zhí)行。
css3動(dòng)畫(huà)有局限性,比如不是所有屬性都能參與動(dòng)畫(huà)、動(dòng)畫(huà)緩動(dòng)效果太少、無(wú)法完全控制動(dòng)畫(huà)過(guò)程等。
requestAnimationFrame()的優(yōu)勢(shì)
它告訴瀏覽器某些JavaScript代碼將要執(zhí)行動(dòng)畫(huà),瀏覽器可以再運(yùn)行某些代碼后進(jìn)行適當(dāng)?shù)膬?yōu)化,十分精確,沒(méi)有css3的局限問(wèn)題,可對(duì)所有屬性操作,動(dòng)畫(huà)緩動(dòng)效果可以依據(jù)緩動(dòng)公式,十分豐富。
requestAnimationFrame()就是為了繪制canvas而生,再合適不過(guò)了。
代碼實(shí)現(xiàn)
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);
這里展示高級(jí)瀏覽器版本,兼容版請(qǐng)自行g(shù)oogle。
easing緩沖動(dòng)畫(huà)當(dāng)初學(xué)習(xí)的時(shí)候的文章找不到了,大致的理解是:時(shí)間間隔一直,每個(gè)間隔運(yùn)行的距離不同。
//iteration當(dāng)前執(zhí)行次數(shù) //startValue執(zhí)行開(kāi)始的位置 //changeValue需要執(zhí)行到的最終位置 //totalIterations需要執(zhí)行的總次數(shù) easing.easeOutBounce(iteration, startValue, changeValue, totalIterations);
看上面的參數(shù)能了解到,easing產(chǎn)生的是與直線(xiàn)的偏移,iteration表示的是偏移的延續(xù),totalIterations表示的動(dòng)畫(huà)進(jìn)行速度,startValue表示的是偏移的起始,changeValue表示的是偏移的量。
canvas方法用到的一些canvas方法:
fillRect():在畫(huà)布上繪制的矩形會(huì)填充指定顏色,由fillStyle屬性指定
strokeRect():在畫(huà)布上繪制的矩形會(huì)使用指定的顏色描邊,由strokeStyle屬性指定
clearRect():清除畫(huà)布上的矩形區(qū)域
arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)為圓心繪制一條弧線(xiàn),弧線(xiàn)半徑為radius,起始和結(jié)束角度(用弧度表示)分別為startAngle和endAngle。最后一個(gè)參數(shù)表示是否按逆時(shí)針?lè)较蛴?jì)算,值為false表示順時(shí)針?lè)较蛴?jì)算
lineTo(x, y):從上一點(diǎn)開(kāi)始繪制一條直線(xiàn),到(x, y)為止
drawImage(image, x, y, width, height):繪制圖像到畫(huà)布上,參數(shù)有3種,不一一介紹
save()與restore():保存上下文環(huán)境,操作...,恢復(fù)上次保存的上下文環(huán)境
這里只用到了這些,其他方法以后再介紹
css3 3D Transform為了能更酷炫點(diǎn),再加上css3的3D翻轉(zhuǎn)效果
transform-style:指定嵌套元素如何在3D空間中呈現(xiàn)。它主要有兩個(gè)屬性值:flat和preserve-3d,它本身需要設(shè)置在父元素中,如果設(shè)置了transform-style值為preserve-3d,就不能設(shè)置overflow值為hidden
perspective:設(shè)置查看者的位置,并將可視內(nèi)容映射到一個(gè)視錐上,繼而投到一個(gè)2D視平面上,就是視距
perspective-origin:決定perspective屬性的源點(diǎn)角度
transition:過(guò)渡效果
translateZ():使一個(gè)元素在三維空間移動(dòng)
rotateY():指定一個(gè)元素圍繞Y軸旋轉(zhuǎn),旋轉(zhuǎn)的量被定義為指定的角度;如果值為正值,元素圍繞Y軸順時(shí)針旋轉(zhuǎn);反之,如果值為負(fù)值,元素圍繞Y軸逆時(shí)針旋轉(zhuǎn)
這里只用到了這些,不做詳細(xì)介紹,太多了...
準(zhǔn)備工作先進(jìn)行到這里,接下來(lái)進(jìn)行本例的講解。
具體實(shí)現(xiàn)參數(shù)數(shù)組
value:所占比重,百分之幾
color:選中時(shí)顏色
highlight:選中時(shí)鼠標(biāo)懸停時(shí)顏色
grey:未選中時(shí)顏色
greylight:未選中時(shí)鼠標(biāo)懸停時(shí)顏色
我自己設(shè)置傳入的參數(shù):
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" } ];
繪制圓盤(pán)
function drawing (ctx, i) {//傳入canvas的context startValue = endValue;//每個(gè)扇形開(kāi)始繪制的位置 endValue = startValue + Math.PI * pieData[i].value * 2;//每個(gè)扇形結(jié)束繪制的位置 ctx.beginPath();//開(kāi)始繪制 ctx.arc(225, 225, radiusBig, startValue, endValue, false);//繪制扇形的弧線(xiàn) ctx.lineTo(225,225);//繪制扇形鏈接圓心的兩條直線(xiàn) ctx.lineWidth = 2;//設(shè)置線(xiàn)的寬度 ctx.closePath();//結(jié)束繪制 ctx.fillStyle = pieData[i].grey;//設(shè)置扇形顏色 ctx.strokeStyle = "#fff";//設(shè)置線(xiàn)的顏色 ctx.fill();//填充 ctx.stroke();//描邊 }
繪制文字及其位置
putIcon()用來(lái)計(jì)算繪制位置,r為半徑,θ為角度,x = r + r sinθ, y = r - r cosθ,left和top的值為x和y。
(先寫(xiě)在這,本人不會(huì)畫(huà)圖,等學(xué)會(huì)再來(lái)畫(huà))
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) } }
確定交互區(qū)域
確定交互區(qū)域本人的思路是獲取鼠標(biāo)在視口上的(x ,y),再將這個(gè)點(diǎn)是否是可交互區(qū)域,能耗可能會(huì)比較大,沒(méi)想到更好的做法,不過(guò)看到css3的clip-path屬性可以實(shí)現(xiàn)類(lèi)似效果,之后會(huì)研究下。
首先確定點(diǎn)擊區(qū)域?yàn)橥鈱哟髨A與內(nèi)層小圓之間,公式:(x - r) (x - r) + (y - r) (y - r) = r * r;
直線(xiàn)方程:(x - x1)/(x2 - x1) = (y - y1)/(y2 - y1);
兩點(diǎn)即可判斷一條直線(xiàn),先確定圓心點(diǎn)(r, r),再根據(jù)角度確定直線(xiàn)與圓交點(diǎn)(r + r sinθ, y = r - r cosθ)
得到的直線(xiàn)方程為:y = (x - r) (-r cosθ) / (r * sinθ) + r;
相鄰兩條直線(xiàn)建立二元一次不等式組,即可確定中間區(qū)域;
動(dòng)畫(huà)緩動(dòng)
將easing與requestAnimationFrame()的結(jié)合使用,這是實(shí)現(xiàn)掉落效果的動(dòng)畫(huà)
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; //立即執(zhí)行的遞歸方法 (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實(shí)現(xiàn)3D翻轉(zhuǎn)效果
最外層設(shè)置視距perspective: 2000px;perspective-origin:right top;
父級(jí)設(shè)置transition: all 0.7s ease-out;transform-style: preserve-3d;子級(jí)設(shè)置left和top為自身高寬的一半,使圓心位置為翻轉(zhuǎn)中心點(diǎn),back-c為背面,front-c為正面,改變r(jià)otatey(0deg)為rotatey(-180deg)表示從正面翻轉(zhuǎn)180度到背面,反之亦然,translateZ()在這里用來(lái)表示層疊關(guān)系,一層蓋在另一層上面。
.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內(nèi)容
寫(xiě)了很多canvas,white-c是翻轉(zhuǎn)之后蓋在上面的白色小圓,每次繪制都要畫(huà)一次,所以拿出來(lái)減少能耗,text-c也是出于這個(gè)原因,text-c用來(lái)繪制小動(dòng)畫(huà),line-c是拿出來(lái)當(dāng)觸發(fā)器用的,沒(méi)必要單拎出來(lái),只是想?yún)^(qū)分用途才拿出來(lái)的。
總結(jié)
花了點(diǎn)時(shí)間看了下自己的代碼,找尋下迷失的自己,繼續(xù)啟程。
感興趣的看官點(diǎn)擊這里:coding:circle
本文轉(zhuǎn)載自筆者的個(gè)人博客:Gaoxuefeng"s Blog
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79402.html
摘要:最近在做一些活動(dòng)的需求,發(fā)現(xiàn)用到轉(zhuǎn)盤(pán)的機(jī)會(huì)很大。轉(zhuǎn)盤(pán)的旋轉(zhuǎn)控制首先,能夠在點(diǎn)擊轉(zhuǎn)的按鈕時(shí)候做一些判斷是否可以開(kāi)轉(zhuǎn),使用變量來(lái)控制。最近在做一些h5活動(dòng)的需求,發(fā)現(xiàn)用到轉(zhuǎn)盤(pán)的機(jī)會(huì)很大。 代碼已經(jīng)開(kāi)源,感興趣的同學(xué)可查看react-turnplate 先上效果 showImg(https://user-gold-cdn.xitu.io/2019/5/18/16ac949855bdd316); ...
摘要:扇形制作原理,底部一個(gè)純色原形,里面?zhèn)€相同顏色的半圓,可以是白色內(nèi)部半圓按一定角度變化,就可以產(chǎn)生出扇形效果扇形繪制這個(gè)屬性用來(lái)繪制半圓,在的范圍內(nèi)的內(nèi)容顯示出來(lái),使用屬性,元素必須是的繪制一個(gè)度扇形繪制一個(gè)度扇形 扇形制作原理,底部一個(gè)純色原形,里面2個(gè)相同顏色的半圓,可以是白色,內(nèi)部半圓按一定角度變化,就可以產(chǎn)生出扇形效果 扇形繪制 .shanxin...
摘要:扇形制作原理,底部一個(gè)純色原形,里面?zhèn)€相同顏色的半圓,可以是白色內(nèi)部半圓按一定角度變化,就可以產(chǎn)生出扇形效果扇形繪制這個(gè)屬性用來(lái)繪制半圓,在的范圍內(nèi)的內(nèi)容顯示出來(lái),使用屬性,元素必須是的繪制一個(gè)度扇形繪制一個(gè)度扇形 扇形制作原理,底部一個(gè)純色原形,里面2個(gè)相同顏色的半圓,可以是白色,內(nèi)部半圓按一定角度變化,就可以產(chǎn)生出扇形效果 扇形繪制 .shanxin...
閱讀 2816·2021-11-24 09:39
閱讀 1671·2021-09-28 09:35
閱讀 1148·2021-09-06 15:02
閱讀 1364·2021-07-25 21:37
閱讀 2797·2019-08-30 15:53
閱讀 3675·2019-08-30 14:07
閱讀 735·2019-08-30 11:07
閱讀 3553·2019-08-29 18:36