做者:凹凸曼 - 阿文css
在 web 應用中,前端同窗在實現動畫效果時每每經常使用的幾種方案:html
在大多數需求中,css3 的 transition / animation
都能知足咱們的需求,而且相對於 js 實現,能夠大大提高咱們的開發效率,下降開發成本。前端
本篇文章將着重對 animation
的使用作個總結,若是你的工做中動畫需求較多,相信本篇文章可以讓你有所收穫:css3
Animation 與 Svg 又會擦出怎樣的火花呢?🔥web
Animation steps() 運用 ⏰segmentfault
介紹完 animation 經常使用屬性,爲了將這些屬性更好地理解與運用,下面將手把手實現一些 DEMO 具體講述瀏覽器
實現不間斷播報 DEMO app
經過修改內容在父元素中的 y 軸的位置來實現廣播效果svg
@keyframes scroll { 0%{ transform: translate(0, 0); } 100%{ transform: translate(0, -$height); } } .ul { animation-name: scroll; animation-duration: 5s; animation-timing-function: linear; animation-iteration-count: infinite; /* animation: scroll 5s linear infinite; 動畫屬性簡寫 */ }
此處爲了保存廣播滾動效果的連貫性,防止滾動到最後一幀時沒有內容,須要多添加一條重複數據進行填充函數
<div class="ul"> <div class="li">小劉同窗加入了凹凸實驗室</div> <div class="li">小鄧同窗加入了凹凸實驗室</div> <div class="li">小李同窗加入了凹凸實驗室</div> <div class="li">小王同窗加入了凹凸實驗室</div> <!-- 插入用於填充的數據數據 --> <div class="li">小劉同窗加入了凹凸實驗室</div> </div>
經過將過渡動畫拆分爲多個階段,每一個階段的 top 屬性停留在不一樣的位置來實現
/* 規定動畫,改變top,opacity */ @keyframes animate { 0% { top: -100%; opacity: 0; } 25% { top: 60; opacity: 1; } 50% { top: 48%; opacity: 1; } 75% { top: 52%; opacity: 1; } 100%{ top: 50%; opacity: 1; } }
爲了讓過渡效果更天然,這裏經過 cubic-bezier()
函數定義一個貝塞爾曲線來控制動畫播放速度
過渡動畫執行完後,爲了將讓元素應用動畫最後一幀的屬性值,咱們須要使用 animation-fill-mode: forwards
.popup { animation-name: animate; animation-duration: 0.5s; animation-timing-function: cubic-bezier(0.21, 0.85, 1, 1); animation-iteration-count: 1; animation-fill-mode: forwards; /* animation: animate 0.5s cubic-bezier(0.21, 0.85, 1, 1) 1 forwards; 動畫屬性簡寫 */ }
相信大多數同窗都知道點贊效果,本文章會實現一個簡易版的點贊效果,主要講述一下實現思路:
/* 規定動畫,改變y軸偏移距離*/ @keyframes animation-y { 0%{ transform: translate(-50%, 100px) scale(0); } 50%{ transform: translate(-50%, -100px) scale(1.5); } 100%{ transform: translate(-50%, -300px) scale(1.5); } }
/* 規定動畫,改變x軸偏移距離 */ @keyframes animation-x { 0%{ margin-left: 0px; } 25%{ margin-left: 25px; } 75%{ margin-left: -25px; } 100%{ margin-left: 0px; } }
這裏我理解:
修改 margin
來改變 x 軸偏移距離,但實際上與修改 transform
沒有太大的性能差別@keyframes animation-y
中的 transform
已經新建了一個渲染層 ( PaintLayers )
animation
屬性 可讓該渲染層提高至 合成層(Compositing Layers)
擁有單獨的圖形層 ( GraphicsLayer )
,即開啓了硬件加速 ,不會影響其餘渲染層的 paint、layout
合成層(Compositing Layers)
相關知識不是很瞭解的同窗,能夠閱讀一下這篇文章從瀏覽器渲染層面解析 css3 動效優化原理如筆者這裏理解有誤,還請讀者大佬指出,感激涕零~
.bubble { animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1; /* 給 bubble 開啓了硬件加速 */ }
function like() { const likeDom = document.createElement('div'); likeDom.className = 'bubble'; // 添加樣式 document.body.appendChild(likeDom); // 添加元素 setTimeout( () => { document.body.removeChild(likeDom); // 移除元素 }, 4000) }
Animation 與 Svg 繪製 loading/進度條 組件 🔥 DEMO
2 * 25 * PI = 157
的圓<svg with='200' height='200' viewBox="0 0 100 100" > <circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke="#0079f5" ></circie> </svg>
stoke-dasharray:50, 50 (可簡寫爲50)
屬性來繪製虛線, stoke-dasharray 參考資料短劃線(50px)
和缺口(50px)
的長度。50(短劃線) + 50(缺口) + 50(段劃線) = 150, 150 < 157
,沒法繪製出完整的圓,因此會致使右邊存在缺口(7px)
<svg with='200' height='200' viewBox="0 0 100 100" > <circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke-dasharray="50" stroke="#0079f5" ></circie> </svg>
stroke-dashoffset
屬性可使圓的短劃線和缺口產生偏移,添加 @keyframes 動畫後可以實現從無到有的效果,stoke-dashoffset 參考資料stroke-dasharray="157 157
",指定 短劃線(157px)
和 缺口(157px)
的長度。修改stroke-dashoffset值
, 值爲正數
時逆時針偏移
🔄,, 值爲負數
時,順時針偏移
🔃@keyframes loading { 0%{ stroke-dashoffset: 0; } 100%{ stroke-dashoffset: -157; /* 線條順時針偏移 */ } } circle{ animation: loading 1s 0s ease-out infinite; }
50px
的短劃線,設置 stroke-dasharray="50"
缺口須要大於或等於圓周長157
,設置 stroke-dasharray="50 157"
動畫結束時仍處理動畫開始位置
,須要修改 stroke-dashoffset:-207(短劃線+缺口長度)
stroke-dashoffset
屬性,具體實現請查看示例@keyframes loading { 0%{ stroke-dashoffset: 0; } 100%{ stroke-dashoffset: -207; /* 保證動畫結束時仍處理動畫開始位置 */ } } circle{ animation: loading 1s 0s ease-out infinite; }
steps()
是 animation-timing-function
的屬性值
animation-timing-function : steps(number[, end | start])
兩個參數
第一個參數接受一個整數值
,表示兩個關鍵幀之間分幾步完成第二個參數有兩個值 start or end
。默認值爲 endsteps 適用於關鍵幀動畫,第一個參數將兩個關鍵幀
細分爲N幀
,第二個參數決定從一幀到另外一幀的中間間隔是用開始幀
仍是結束幀
來進行填充。
看下圖能夠發現:
steps(N, start)
將動畫分爲N段
,動畫在每一段的起點
發生階躍(即圖中的空心圓 → 實心圓),動畫結束時停留在了第 N 幀steps(N, end)
將動畫分爲N段
,動畫在每一段的終點
發生階躍(即圖中的空心圓 → 實心圓),動畫結束時第 N 幀已經被跳過(即圖中的空心圓 → 實心圓),停留在了 N+1 幀。13
個字符。[經測試,多數中文字體每一個字符寬高都相等]steps(13)
能夠將 @keyframes 動畫分爲13階段
運行,且每一階段運行距離相等
。效果以下:
/* 改變容器寬度 */ @keyframes animate-x { 0%{ width: 0; } } p { width: 125px; overflow: hidden; border-right: 1px solid transparent; animation: animate-x 3s 0s steps(13) 1 forwards; }
每一個字符的width與動畫每一階段運行的距離相等
Monaco
字體屬性,用以保證每一個字符的 width 相同
,具體像素受fontSize
屬性影響,示例中的字體寬度約爲 9.6px,9.6px * 13(段數) = 124.8px (125px)
,因此當咱們設置容器寬度爲 125px,便可的達成目的:每一個字符的 width 與動畫每一階段運行的距離相等(約爲 9.6px )
。p { /* 設置 Monaco 字體屬性,字體大小爲16px,用以保證每一個字符的 width 相同,width 約爲9.6p */ font-family: Monaco; /* 9.6px * 13 = 124.8px (125px) */ width: 125px ; font-size: 16px; overflow: hidden; border-right: 1px solid transparent; /* 同時應用動畫 animate-x、cursor-x */ animation: animate-x 3s 0s steps(13) 1 forwards,cursor-x 0.4s 0s linear infinite; }
47幀
的雪碧圖(css spirit),設置背景圖.main { width: 260px; height: 200px; background: url(url) no-repeat; background-size: 100%; background-position: 0 0; }
修改 background-position
,讓背景圖移動@keyframes animate { 0% { background-position: 0 0; } 100% { background-position: 0 100%; } } .main{ width: 260px; height: 200px; background: url(url) no-repeat; background-size: 100%; background-position: 0 0; animation: animate 2s 1s steps(47) infinite alternate; }
animation-play-state
用於控制動畫是否暫停input:checked+.main{ animation-play-state: paused; }
文章篇幅較長,感謝你們的閱讀,但願各位看客可以有所收穫~ ~ ~
Animation 經常使用動畫屬性
CSS 參考手冊
steps() 參考資料
SVG 學習之 stroke-dasharray 和 stroke-dashoffset 詳解
理解 CSS3 Animation 中的 steps()
【譯】css 動畫裏的 steps()用法詳解
CSS Will Change
歡迎關注凹凸實驗室博客:aotu.io
或者關注凹凸實驗室公衆號(AOTULabs),不定時推送文章。