animation停留_这些Animation动画技巧与细节你知道么
引言—
在 web 應(yīng)用中,前端同學(xué)在實現(xiàn)動畫效果時往往常用的幾種方案:
在大多數(shù)需求中,css3 的 transition / animation 都能滿足我們的需求,并且相對于 js 實現(xiàn),可以大大提升我們的開發(fā)效率,降低開發(fā)成本。
本篇文章將著重對 animation 的使用做個總結(jié),如果你的工作中動畫需求較多,相信本篇文章能夠讓你有所收獲:
- Animation 常用動畫屬性
- Animation 實現(xiàn)不間斷播報
- Animation 實現(xiàn)回彈效果
- Animation 實現(xiàn)直播點贊效果 ??
- Animation 與 Svg 又會擦出怎樣的火花呢??
Animation 常用動畫屬性—
介紹完 animation 常用屬性,為了將這些屬性更好地理解與運用,下面將手把手實現(xiàn)一些 DEMO 具體講述
Animation 實現(xiàn)不間斷播報—
實現(xiàn)不間斷播報 DEMO [1]
通過修改內(nèi)容在父元素中的 y 軸的位置來實現(xiàn)廣播效果
@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; 動畫屬性簡寫 */
}
此處為了保存廣播滾動效果的連貫性,防止?jié)L動到最后一幀時沒有內(nèi)容,需要多添加一條重復(fù)數(shù)據(jù)進(jìn)行填充
<div class="ul"><div class="li">小劉同學(xué)加入了凹凸實驗室div>
<div class="li">小鄧同學(xué)加入了凹凸實驗室div>
<div class="li">小李同學(xué)加入了凹凸實驗室div>
<div class="li">小王同學(xué)加入了凹凸實驗室div>
<div class="li">小劉同學(xué)加入了凹凸實驗室div>
div>
Animation 實現(xiàn)回彈效果—
通過將過渡動畫拆分為多個階段,每個階段的 top 屬性停留在不同的位置來實現(xiàn)
實現(xiàn)回彈效果 DEMO[2]
/* 規(guī)定動畫,改變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() 函數(shù)定義一個貝塞爾曲線來控制動畫播放速度
過渡動畫執(zhí)行完后,為了將讓元素應(yīng)用動畫最后一幀的屬性值,我們需要使用 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; 動畫屬性簡寫 */
}
Animation 實現(xiàn)點贊效果—
實現(xiàn)點贊效果 DEMO [3]
相信大多數(shù)同學(xué)都知道點贊效果,本文章會實現(xiàn)一個簡易版的點贊效果,主要講述一下實現(xiàn)思路:
@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);
}
}
@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 已經(jīng)新建了一個渲染層 ( PaintLayers )
- animation 屬性 可以讓該渲染層提升至 合成層(Compositing Layers) 擁有單獨的圖形層 ( GraphicsLayer ),即開啟了硬件加速 ,不會影響其他渲染層的 paint、layout
- 對于合成層(Compositing Layers)相關(guān)知識不是很了解的同學(xué),可以閱讀一下凹凸實驗室(http://aotu.io)的文章《從瀏覽器渲染層面解析 css3 動效優(yōu)化原理》
- 如下圖所示:
如筆者這里理解有誤,還請讀者大佬指出,感激不盡~
animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1;
/* 給 bubble 開啟了硬件加速 */
}
const likeDom = document.createElement('div');
likeDom.className = 'bubble'; // 添加樣式
document.body.appendChild(likeDom); // 添加元素
setTimeout( () => {
document.body.removeChild(likeDom); // 移除元素
}, 4000)
}
Animation 與 Svg 繪制 loading/進(jìn)度條 組件 ?—
Animation 與 Svg 繪制 loading/進(jìn)度條 組件 ? DEMO [4]
<circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke="#0079f5" >circie>
svg>
- 它的值是一個數(shù)列,數(shù)與數(shù)之間用逗號或者空白隔開,指定短劃線(50px)和缺口(50px)的長度。
- 由于50(短劃線) + 50(缺口) + 50(段劃線) = 150, 150 < 157,無法繪制出完整的圓,所以會導(dǎo)致右邊存在缺口(7px)
<circle cx="50" cy="50" r="25" fill="transparent" stroke-width="4" stroke-dasharray="50" stroke="#0079f5" >circie>
svg>
- 設(shè)置 stroke-dasharray="157 157",指定 短劃線(157px) 和 缺口(157px) 的長度。
- 添加 @keyframes 動畫 修改stroke-dashoffset值, 值為正數(shù)時逆時針偏移?,, 值為負(fù)數(shù)時,順時針偏移?
0%{
stroke-dashoffset: 0;
}
100%{
stroke-dashoffset: -157; /* 線條順時針偏移 */
}
}
circle{
animation: loading 1s 0s ease-out infinite;
}
- 為了讓 loading 組件線條可見,我們需要一個50px的短劃線,設(shè)置 stroke-dasharray="50"
- 為了讓短劃線發(fā)生偏移后可以完全消失,缺口需要大于或等于圓周長157,設(shè)置 stroke-dasharray="50 157"
- 添加 @keyframes 動畫,為了讓動畫結(jié)束時仍處理動畫開始位置,需要修改 stroke-dashoffset:-207(短劃線+缺口長度)
- 進(jìn)度條也是類似原理,幫助理解 stroke-dashoffset 屬性,具體實現(xiàn)請查看示例[7]
0%{
stroke-dashoffset: 0;
}
100%{
stroke-dashoffset: -207; /* 保證動畫結(jié)束時仍處理動畫開始位置 */
}
}
circle{
animation: loading 1s 0s ease-out infinite;
}
Animation steps()運用—
steps() 是 animation-timing-function 的屬性值
animation-timing-function : steps(number[, end | start])- steps 函數(shù)指定了一個階躍函數(shù),它接受兩個參數(shù)
- 第一個參數(shù)接受一個整數(shù)值,表示兩個關(guān)鍵幀之間分幾步完成
- 第二個參數(shù)有兩個值 start or end。默認(rèn)值為 end
- step-start 等同于 step(1, start)。step-end 等同于 step(1, end)
steps 適用于關(guān)鍵幀動畫,第一個參數(shù)將兩個關(guān)鍵幀細(xì)分為N幀,第二個參數(shù)決定從一幀到另一幀的中間間隔是用開始幀還是結(jié)束幀來進(jìn)行填充。
看下圖可以發(fā)現(xiàn):
- steps(N, start)將動畫分為N段,動畫在每一段的起點發(fā)生階躍(即圖中的空心圓 → 實心圓),動畫結(jié)束時停留在了第 N 幀
- steps(N, end)將動畫分為N段,動畫在每一段的終點發(fā)生階躍(即圖中的空心圓 → 實心圓),動畫結(jié)束時第 N 幀已經(jīng)被跳過(即圖中的空心圓 → 實心圓),停留在了 N+1 幀。
實踐出真知!—
Animation 實現(xiàn)打字效果
Animation 實現(xiàn)打字效果 DEMO[8]
- 此處用英文字母(I'm an O2man.)舉例,一共有13個字符。[經(jīng)測試,多數(shù)中文字體每個字符寬高都相等]
- steps(13)可以將 @keyframes 動畫分為13階段運行,且每一階段運行距離相等。
效果如下:
/* 改變?nèi)萜鲗挾?*/@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;
}
- 可以發(fā)現(xiàn)僅僅這樣還不夠,動畫運行過程中出現(xiàn)了字符被截斷的情況,為了保證每個階段運行后能準(zhǔn)確無誤地顯示當(dāng)前所處階段的字符,我們還需要保證每個字符的width與動畫每一階段運行的距離相等
- 設(shè)置Monaco字體屬性,用以保證每個字符的 width 相同,具體像素受fontSize屬性影響,示例中的字體寬度約為 9.6px,9.6px * 13(段數(shù)) = 124.8px (125px),所以當(dāng)我們設(shè)置容器寬度為 125px,即可的達(dá)成目的:每個字符的 width 與動畫每一階段運行的距離相等(約為 9.6px )。
/* 設(shè)置 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;
/* 同時應(yīng)用動畫 animate-x、cursor-x */
animation: animate-x 3s 0s steps(13) 1 forwards,cursor-x 0.4s 0s linear infinite;
}
Animation 實現(xiàn)幀動畫 ?
Animation 實現(xiàn)幀動畫 ? DEMO [9]
- 這里我們拿到了一張47幀的雪碧圖(css spirit)[10],設(shè)置背景圖
width: 260px;
height: 200px;
background: url(url) no-repeat;
background-size: 100%;
background-position: 0 0;
}
- 添加 @keyframes 修改 background-position,讓背景圖移動
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;
}
- 同時, css 還提供了animation-play-state用于控制動畫是否暫停
animation-play-state: paused;
}
文章篇幅較長,感謝大家的閱讀,希望各位看客能夠有所收獲~ ~ ~
相關(guān)參考資料
《Animation 常用動畫屬性》[11]
《CSS 參考手冊》[12]
《steps 參考資料》[13]
《SVG 學(xué)習(xí)之 stroke-dasharray 和 stroke-dashoffset 詳解》[14]
《理解 CSS3 Animation 中的 steps》[15]
《【譯】css 動畫里的 steps 用法詳解》[16]
《CSS Will Change》[17]
參考資料
[1]實現(xiàn)不間斷播報 DEMO : https://codepen.io/awesomedevin/pen/wvMGEaY
[2]實現(xiàn)回彈效果 DEMO: https://codepen.io/awesomedevin/pen/wvMGEaY
[3]實現(xiàn)點贊效果 DEMO : https://codepen.io/awesomedevin/pen/dyGXEar
[4]Animation 與 Svg 繪制 loading/進(jìn)度條 組件 ? DEMO : https://codepen.io/awesomedevin/pen/zYromBB
[5]stoke-dasharray 參考資料: https://www.cnblogs.com/daisygogogo/p/11044353.html
[6]stoke-dashoffset 參考資料: https://www.cnblogs.com/daisygogogo/p/11044353.html
[7]示例: https://codepen.io/awesomedevin/pen/zYromBB
[8]Animation 實現(xiàn)打字效果 DEMO: https://codepen.io/awesomedevin/pen/xxZEjjO
[9]Animation 實現(xiàn)幀動畫 ? DEMO : https://codepen.io/awesomedevin/pen/JjGRMgN
[10]雪碧圖(css spirit): https://img11.360buyimg.com/ling/jfs/t1/142743/11/2314/166268/5f046114Efb97efac/b327092864ed1f04.png
[11]Animation 常用動畫屬性: https://www.w3school.com.cn/cssref/index.asp
[12]CSS 參考手冊: https://www.w3school.com.cn/cssref/index.asp
[13]steps 參考資料: https://segmentfault.com/a/1190000007042048
[14]SVG 學(xué)習(xí)之 stroke-dasharray 和 stroke-dashoffset 詳解: https://www.cnblogs.com/daisygogogo/p/11044353.html
[15]理解 CSS3 Animation 中的 steps: https://laixiazheteng.com/article/page/id/0gU2Wefas7hn
[16]【譯】css 動畫里的 steps 用法詳解: https://segmentfault.com/a/1190000007042048
[17]CSS Will Change: https://developer.mozilla.org/zh-CN/docs/Web/CSS/will-change
聚焦全棧,專注分享 TypeScript、Web API、前端架構(gòu)等技術(shù)干貨。總結(jié)
以上是生活随笔為你收集整理的animation停留_这些Animation动画技巧与细节你知道么的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端进阶系列(六):盒模型
- 下一篇: 寒武纪找到了引领中国AI芯片走向世界的路