摘要:然后在節(jié)點上設(shè)置了動畫屬性,并將其設(shè)為前面定義的動畫,每一次動畫秒,表示無限循環(huán),表示緩動方式,兩個關(guān)鍵幀之間的變化是方式逐步變化的。
平時工作中會遇到需要實現(xiàn)一些存在動畫的頁面。這里對動畫的實現(xiàn)知識做一個整理。
頁面動畫的實現(xiàn)可以分為兩類:CSS動畫、Canvas動畫、JavaScript動畫。JavaScript動畫沒啥好講的,這里就不整理了。
CSS3中提供了一個屬性transition,用來實現(xiàn)CSS樣式的平滑變化。舉個例子:
.box { width: 100px; height: 100px; background: red; transition: width 1s; } .box:hover { width: 300px; }
當(dāng)鼠標(biāo)hover到.box元素時,元素會在1s內(nèi)逐漸的將寬度變化到300px。
具體效果可以去這里查看。
使用transition可以實現(xiàn)較為簡單的動畫。如果需要實現(xiàn)比較復(fù)雜的動畫,可以使用amination來實現(xiàn)。舉個例子:
@keyframes cssAmination { 0% {background: red; transform: skew(0deg);} 25% {background: yellow; transform: skew(-20deg);} 50% {background: blue; transform: skew(0deg);} 75% {background: green; transform: skew(20deg);} 100% {background: red; transform: skew(0deg);} } .amin { animation: cssAmination 1s infinite ease; }
在上的例子中,首先由keyframes定義一個動畫叫做: cssAnimation。在cssAnimation中定義了動畫過程中關(guān)鍵的5幀。每一幀都設(shè)置了當(dāng)前幀的樣式特征。然后在.amin節(jié)點上設(shè)置了動畫屬性animation,并將其設(shè)為前面定義的動畫cssAnimation,每一次動畫1秒,infinite表示無限循環(huán),ease表示緩動方式,兩個關(guān)鍵幀之間的變化是ease方式逐步變化的。
具體效果可以到這里查看
animation的緩動函數(shù)有很多類型的值,有一個值比較特別就是step[n[, start | end]]。step的效果是將keyframes中的每一個關(guān)鍵幀之間的切換并不是逐步變化的,而是到達某一關(guān)鍵幀后直接變化成新的關(guān)鍵幀樣式,并保持不變,直到下一關(guān)鍵幀。所以使用step可以實現(xiàn)CSS3的幀動畫。寫法如下:
@keyframes cssFrameAmination { 0% {background-position: 0 0;} 25% {background-position: -100px 0;} 50% {background-position: -200px 0;} 75% {background-position: -300px 0;} 100% {background-position: -400px 0;} } .amin-frame { background: url("./sprite.png") 0 0 no-repeat; animation: cssFrameAmination 1s infinite step(5, start); }
在上面的例子中,設(shè)置動畫cssFrameAmination,其中每一關(guān)鍵幀都是精靈動畫圖片的一幀圖片。然后在animation中設(shè)置animation-timing-function為step(5, start)表示動畫分5幀。
有關(guān)CSS3動畫相關(guān)的知識細(xì)節(jié)可以去這里了解。
Canvascanvas是一個HTML標(biāo)簽,用于提供給腳本進行畫圖圖形的繪制。canvas的繪制主要由CanvasRenderingContext2D的實例來進行繪制。CanvasRenderingContext2D 可以通過canvasDOM對象的getContext獲得,代碼如下:
const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d");
繪制圖形getContext的參數(shù)是指在畫布上繪制的類型,"2d"表示繪制二維圖形。目前三維還沒有實現(xiàn),所以參數(shù)只支持"2d"。
canvas的上下文提供了眾多的繪制方法。當(dāng)你繪制一個圖形時,基本思路是這樣的:
調(diào)用save方法保存之前的樣式狀態(tài)
調(diào)用beginPath表示開始設(shè)置路徑
調(diào)用fillStyle, strokeStyle等對接下來的路徑進行樣式設(shè)置
調(diào)用moveTo,lineTo, rect, arc等設(shè)置路徑
調(diào)用closePath閉合路徑
調(diào)用fill或者stroke對路徑進行繪制
調(diào)用restore恢復(fù)之前保存的樣式狀態(tài)
上面過程中的save和restore的作用是將已經(jīng)設(shè)置的樣式進行保存和恢復(fù)。當(dāng)存在多個圖形時,前面的樣式如果不恢復(fù)為默認(rèn)樣式,會影響到第二個圖形的樣式。使用save和restore可以保證每一個圖形在繪制開始時,都是默認(rèn)的樣式。當(dāng)然,你也可以不調(diào)用save和restore,而是通過將前面已經(jīng)設(shè)置過的所有樣式進行逐個的還原。
save可以保存的樣式類型有:
當(dāng)前應(yīng)用的變形(即移動,旋轉(zhuǎn)和縮放)
strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
當(dāng)前的裁切路徑(clipping path)
步驟5closePath盡量不要忘記。原因和save,restore類似,如果忘記調(diào)用closePath就會導(dǎo)致前后圖形間多繪制一根線。
我寫了一個時鐘的例子:github
下面對各類接口做了一個整理
樣式設(shè)置
接口名 | 接口描述 |
---|---|
顏色 | |
fillStyle | 圖形填充顏色 |
strokeStyle | 圖形輪廓顏色 |
globalAlpha | 圖形全局透明度 |
陰影 | |
shadowOffsetX, shadowOffsetY | 陰影方向 |
shadowBlur | 設(shè)定陰影的模糊程度 |
shadowColor | 陰影的顏色值 |
線型 | |
lineWidth | 線條寬度(int) |
lineCap | 線條末端樣式(butt: 平直; round: 添加半圓; square: 添加方形) |
lineJoin | 設(shè)置線條間的接合處(bevel: 斜角; round: 圓角; miter: 尖角) |
miterLimit | 兩線相交時尖角最大長度(lineJoin:miter時生效,過長不顯示) |
getLineDash | 返回當(dāng)前虛線樣式(數(shù)組) |
setLineDash | 設(shè)置虛線樣式(數(shù)組) |
lineDashOffset | 設(shè)置虛線樣式起始偏移量 |
漸變 | |
createLinearGradient(x1, y1, x2, y2) | 線性漸變 |
createRadialGradient(x1, y1, r1, x2, y2, r2) | 圓漸變, 漸變反向是從圓心向外發(fā)散 |
gradient.addColorStop(position, color) | 對生成的gradient對象添加結(jié)束顏色。position是中間過程,取值0~1 |
圖案樣式 | |
createPattern(imageOrCanvas, type) | 創(chuàng)建圖片填充對象。image必須是已加載完畢的;type: repeat, repeat-x, repeat-y, no-repeat |
路徑
接口名 | 描述 |
---|---|
moveTo(x, y) | 移動路徑繪制的起始點 |
beginPath() | 新建一條路徑 |
closePath() | 閉合路徑 |
lineTo(x, y) | 從開始位置繪制路徑到目標(biāo)位置 |
rect(x, y, width, height) | 繪制矩形路徑 |
arc(x, y, radius, startAngle, endAngle, anticlockwise) | 繪制圓弧:x,y為圓心;radius為半徑;startAngle,endAngle為起止位置;anticlockwise為反向(順時針,逆時針) |
arcTo(x1, y1, x2, y2, radius) | 繪制圓弧,并連接控制點 |
quadraticCurveTo(cp1x, cp1y, x, y) | x,y為結(jié)束點; cp1x,xp1y為控制點 |
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) | x,y為結(jié)束點;cp1x,cp1y為控制點1; cp2x,cp2y為控制點2 |
clip() | 裁剪區(qū)域,區(qū)域外的不會發(fā)生繪制 |
繪制
接口名 | 描述 |
---|---|
fillRect(x, y, width, height) | 繪制填充矩形,等同于rect(); fill(); |
strokeRect(x, y, width, height) | 繪制矩形邊框。等同于rect(); stroke() |
fill() | 填充路徑的內(nèi)容區(qū)域 |
stroke() | 通過路徑線條繪制圖形輪廓 |
清除
接口名 | 描述 |
---|---|
clearRect(x, y, width, height) | 清除指定矩形區(qū)域 |
文字
接口名 | 描述 |
---|---|
font | 設(shè)置文字樣式,同css的font |
textAlign | 對其方式 |
textBaseLine | 基線對其 |
direction | 文本方向 |
fillText(text, x, y [, maxWidth]) | 繪制文字填充內(nèi)容 |
strokeText(text, x, y [, maxWidth]) | 繪制文字邊框內(nèi)容 |
measureText(text) | 返回文本的信息 |
樣式保存
接口名 | 描述 |
---|---|
save() | 保存當(dāng)前樣式 |
restore() | 恢復(fù)之前保存樣式 |
canvas雖然可以繪制圖形,但是最常用的應(yīng)該是繪制圖片。圖片的繪制和圖形的繪制類似。
canvas使用接口drawImage()進行接口繪制,接口定義如下:
drawImage(image, x, y, width, height, dx, dy, dWidth, dHeight);
其中的參數(shù)定義如下:
image可以使HTMLImageElement, HTMLVideoElement(Video元素的某一幀), HTMLCanvasElement, ImageBitmap。
x, y是指圖片截取的起始位置。
width, height是指圖片截取的寬高。
dx, dy是目標(biāo)在Canvas中的起始坐標(biāo)。
dWidth, dHeight用于控制canvas繪制的圖片的縮放大小。
圖片變形canvas還可以和CSS一樣對圖形進行變形轉(zhuǎn)化。接口列表如下:
接口名字 | 描述 |
---|---|
translate(x, y) | 偏移。x,y是偏移量 |
rotate(angle) | 旋轉(zhuǎn)角度,順時針 |
scale(x, y) | 縮放。x, y分別是橫軸,縱軸的縮放比例 |
transform(m11, m12, m21, m22, dx, dy) | 變形矩陣轉(zhuǎn)化 |
前面的例子中,當(dāng)兩個圖形重疊后,都是由后面繪制的圖形覆蓋住前面繪制的圖形。有時候需要改變這種情況。這種時候就可以使用globalCompositeOperation來進行設(shè)置(還可以用來遮蓋,清除某些區(qū)域)。具體參數(shù)可以去這里查看
globalCompositeOperation: type動畫實現(xiàn)
使用上面的接口可以在canvas上繪制圖片,但是都是固定的。當(dāng)我們不斷的對canvas進行重繪時,就可以達到動畫的而效果。
動畫的幀率達到60幀每秒時,也就是16ms沒幀時,動畫過程是流暢的。所以我們要對動畫過程的繪制進行控制。有三個方法可以進行控制:
setInterval。設(shè)置每16ms執(zhí)行一次繪制過程。但是該方法存在一個問題,開始運行繪制函數(shù)的時間點可能處于某一幀的快結(jié)束時間點。這個時候繪制過程需要小于16ms才可以達到流暢。
setTimeout。和setInterval類似。
requestAnimationFrame。該方法會在瀏覽器每一次繪制結(jié)束后調(diào)用一次。使用該方法可以很好的避免setInterval和setTimeout出現(xiàn)的運行繪制函數(shù)時間不在每一幀開始的時間點。
Canvas性能創(chuàng)建一個離屏canvas, 預(yù)先對復(fù)雜圖形進行繪制。
避免浮點數(shù)的坐標(biāo)點, 使用Math.floor()對坐標(biāo)取整。
不要使用drawImage去縮放圖片。
使用多canvas繪制復(fù)雜場景。
使用CSS設(shè)置大背景圖。
Canvas調(diào)試查了很多資料,發(fā)現(xiàn)Chrome 44版本之前是有Canvas調(diào)試功能的,但是Chrome 44之后,將Canvas調(diào)試功能去除了,并以擴展接口的方式提供功能。找了很久沒有找到調(diào)試Canvas的擴展。另外,F(xiàn)irefox有提供專門的Canvas調(diào)試面板。試用了下,功能太少,對定位問題并沒什么軟用。
所以,關(guān)于調(diào)試的問題,只能試用傳統(tǒng)的設(shè)斷點,并逐步運行看效果進行調(diào)試。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79632.html
摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...
摘要:同時,由于本身的實現(xiàn)大部分是純函數(shù),因此在版本中,一些不含副作用的均在中暴露了以為前綴的函數(shù)方法,也可以直接導(dǎo)入使用。在瀏覽器中神秘丟失嘗試檢查被請求的是否存在尾部斜線,具體原因暫時沒有找到相關(guān)資料。 寫在前面 最近沒怎么寫新的東西,一是因為一直在準(zhǔn)備換新的工作,所以一直在準(zhǔn)備面試,二是因為過年,心靜不下來,所以也無法輸出或者翻譯一些文章,三是由于手頭還有一些遺留工作需要完成和交接,比...
閱讀 1701·2021-09-26 09:55
閱讀 3734·2021-09-22 15:31
閱讀 7427·2021-09-22 15:12
閱讀 2219·2021-09-22 10:02
閱讀 4692·2021-09-04 16:40
閱讀 1074·2019-08-30 15:55
閱讀 3031·2019-08-30 12:56
閱讀 1820·2019-08-30 12:44