帶你玩轉(zhuǎn)css3動畫-animation

寫在前面

總結(jié)是一種學(xué)習(xí)方式慎菲,取長補短是一種學(xué)習(xí)態(tài)度

我們今天聊一些你不知道的 CSS3 Animation课幕。很多人都覺得 css3 很容易厦坛,不用怎么學(xué),就能熟練掌握乍惊,但是一個不懂 css3 動畫的前端工程師不能稱之為掌握 css3杜秸。在日常開發(fā)中遇到一些要做動畫的模塊就毫無頭緒,要不就是用 js 來寫動畫润绎,所以亩歹,把平時在工作用過的一些 css3 動畫做一個總結(jié),讓大家在以后能更順手的使用動畫來提高自己的頁面逼格凡橱。

animation 屬性是 8 個屬性的簡寫:

animation屬性
animation屬性理解

通過幾個例子來了解一下 animation 動畫,看如何用 animation 來打造各種各樣的動畫亭姥,讓你的頁面更加酷炫稼钩。

你是否被gif loading加載太慢或有鋸齒而感到困擾?

項目中达罗,當(dāng)頁面內(nèi)容或圖片比較多或在加載一些比較大的數(shù)據(jù)接口的時候坝撑,加載時間會比較長静秆,此時可能出現(xiàn)頁面白屏的情況,用戶體驗較差巡李。為了讓用戶會有一個等待的效果抚笔,會在加載成功前顯示一個 loading 來過渡,當(dāng)頁面完全加載完后侨拦,讓 loading 消失即可殊橙。
loading 可以用 gif loading 顯示,但是狱从,優(yōu)雅的前端工程師覺得這樣又多了一個請求和有時候也會加載太慢膨蛮,于是,他奇思妙想季研,覺得可以用純 css loading 來達(dá)到效果敞葛。

css loading
<div class="box">
    <div class="loader">
        <div class="loading-1">
            <i></i>
        </div>
    </div>
    <div class="loader">
        <div class="loading-2">
            <i></i><i></i><i></i><i></i><i></i>
        </div>
    </div>
    <div class="loader">
        <div class="loading-3">
            <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
        </div>
    </div>
</div>

關(guān)鍵的css樣式

.loading-1{width:35px;height:35px;position:relative}
@-webkit-keyframes loading-1{
    0%{transform:rotate(0)}
    50%{transform:rotate(180deg)}
    100%{transform:rotate(360deg)}
}
.loading-1 i{display:block;width:100%;height:100%;border-radius:50%;background:linear-gradient(transparent 0,transparent 70%,#333 30%,#333 100%);-webkit-animation:loading-1 .6s linear 0s infinite}

@-webkit-keyframes loading-2{
    0%{transform:scale(1)}
    50%{transform:scale(.4)}
    100%{transform:scale(1)}
}
.loading-2 i{display:inline-block;width:4px;height:35px;margin:0 2px;background:#333;border-radius:2px;-webkit-animation:loading-2 1s ease-in .1s infinite}
.loading-2 i:nth-child(1){-webkit-animation:loading-2 1s ease-in .1s infinite}
.loading-2 i:nth-child(2){-webkit-animation:loading-2 1s ease-in .2s infinite}
.loading-2 i:nth-child(3){-webkit-animation:loading-2 1s ease-in .3s infinite}
.loading-2 i:nth-child(4){-webkit-animation:loading-2 1s ease-in .4s infinite}
.loading-2 i:nth-child(5){-webkit-animation:loading-2 1s ease-in .5s infinite}

@-webkit-keyframes loading-3{
    50%{transform:scale(.4);opacity:.3}
    100%{transform:scale(1);opacity:1}
}
.loading-3{position:relative}
.loading-3 i{display:block;width:15px;height:15px;border-radius:50%;position:absolute;background:#333}
.loading-3 i:nth-child(1){top:25px;left:0;-webkit-animation:loading-3 1s ease 0s infinite}
.loading-3 i:nth-child(2){top:17px;left:17px;-webkit-animation:loading-3 1s ease .12s infinite}
.loading-3 i:nth-child(3){top:0;left:25px;-webkit-animation:loading-3 1s ease .24s infinite}
.loading-3 i:nth-child(4){top:-17px;left:17px;-webkit-animation:loading-3 1s ease .36s infinite}
.loading-3 i:nth-child(5){top:-25px;left:0;-webkit-animation:loading-3 1s ease .48s infinite}
.loading-3 i:nth-child(6){top:-17px;left:-17px;-webkit-animation:loading-3 1s ease .6s infinite}
.loading-3 i:nth-child(7){top:0;left:-25px;-webkit-animation:loading-3 1s ease .72s infinite}
.loading-3 i:nth-child(8){top:17px;left:-17px;-webkit-animation:loading-3 1s ease .84s infinite}

上面例子熊尉,主要通過 css animation 設(shè)置不同時間段的 animation-delay 來延遲展示效果毒租,再通過設(shè)置 animation-iteration-countinfinite 來進(jìn)行無限的轉(zhuǎn)動,展示出 loading 的效果砍的,給人有一種在等待的過程驼卖;代碼非常簡潔實用氨肌,我們可以根據(jù)項目需要,開發(fā)出適用于項目的 loading款慨。

骨架屏:一個比loading更加優(yōu)雅的加載

據(jù)研究儒飒,用戶大概會在 200ms 內(nèi)獲取到界面的具體關(guān)注點,為了優(yōu)化首屏渲染時間這個指標(biāo)檩奠,減少白屏?xí)r間桩了,在數(shù)據(jù)獲取或頁面加載完成之前,給用戶首先展現(xiàn)骨架屏埠戳,骨架屏的樣式井誉、布局和真實數(shù)據(jù)渲染的頁面保持一致,這樣用戶在骨架屏中獲取到關(guān)注點整胃,并能夠預(yù)知頁面什么地方將要展示文字什么地方展示圖片颗圣,這樣也就能夠?qū)㈥P(guān)注焦點移到感興趣的位置。下面是完全通過 HTMLCSS 手寫的就是在項目中通過簡單的模擬骨架屏屁使,來達(dá)到數(shù)據(jù)未請求到數(shù)據(jù)前的過渡在岂。

骨架屏
<div class="skeleton-wrap">
    <div class="skeleton">
        <div class="left-right item"></div><div class="line-zero item"></div><div class="line-one item"></div><div class="line-two item"></div><div class="line-three item"></div>
    </div>
</div>

關(guān)鍵css代碼

.skeleton-wrap {
    box-sizing: border-box;
    height: 8rem;
    background-color: #fff;
    padding: 0;
    .skeleton {
        height: 6rem;
        box-sizing: border-box;
        position: relative;
        animation-duration: 1s;
        animation-fill-mode: forwards;
        animation-iteration-count: infinite;
        animation-name: placeHolderShimmer;
        animation-timing-function: linear;
        background: linear-gradient(to right, #eeeeee, #dddddd 10%, #eeeeee 30%);
        background-size: 400% 400%;
        .item {position: absolute;}
        .left-right {height: 6rem;width: 2rem;top: 0;left: 6rem;background-color: #fff;}
        .line-zero {height: 0.4rem;width: calc(100% - 8rem);background-color: #fff;left: 8rem;top: 0;}
        .line-one {height: 1rem;width: calc(100% - 8rem);background-color: #fff;left: 8rem;top: 2rem;}
        .line-two {height: 1rem;width: 6rem;background-color: #fff;top: 3rem;right: 0rem;}
        .line-three {width: calc(100% - 8rem);height: 2rem;background-color: #fff;bottom: 0;right: 0;}
    }
}
@keyframes placeHolderShimmer {
    0% {background-position: 100% 50%;}
    100% {background-position: 0 50%;}
}

上面例子,通過拉伸背景圖片 background-position蛮寂,動態(tài) animation 設(shè)置背景定位百分比蔽午,改變背景定位,從而計算得到圖片相對容器的不同偏移值酬蹋,以此實現(xiàn)了動畫的效果及老。

background-size: 400% 400%;

這里給 background-position 屬性設(shè)置了兩個值抽莱,第一個值代表水平位置相對容器的偏移,第二個代表垂直位置相對容器的偏移骄恶。

使用百分比設(shè)置 background-position 值時食铐,它會執(zhí)行一個計算實際定位值公式 (container width - image width) * (position x%) = (x offset value),即容器和圖片的寬度差乘上設(shè)置的百分比定位值僧鲁,得到的結(jié)果就是實際的偏移值虐呻,將background-size 的寬度設(shè)置為 400% 的其中一個目的就是,這樣就會和容器產(chǎn)生寬度差悔捶。

最后利用關(guān)鍵幀動畫 keyframes铃慷,設(shè)置 background-positionx坐標(biāo) 的值從 100%0%

@keyframes placeHolderShimmer {
    0% {background-position: 100% 50%;}
    100% {background-position: 0 50%;}
}

假設(shè)容器的寬度是 100px蜕该,那么背景圖片的寬度就是 400px犁柜,利用上邊的公式,第一幀的動畫中堂淡,背景圖相對容器偏移的真實值是 (100px-400px)*100% = -300px 最后一幀實際偏移 (100px-400px)*0% = 0 動畫的過程實際就是一個 3倍 容器寬的線性背景圖片相對于容器的偏移從 -300px0 的變化的過程馋缅。

純css實現(xiàn)紙牌翻轉(zhuǎn)抽獎,實用

平尘畹恚活動專題中萤悴,產(chǎn)品經(jīng)理會給我們提各種各樣的需求,抽獎就是其中的一個主要功能皆的,當(dāng)然抽獎也分許多形式覆履,紙牌翻轉(zhuǎn)就是其中一個,看一下實際需求中用純 css 實現(xiàn)的紙牌翻轉(zhuǎn)效果(邏輯就是點擊紙牌费薄,請求后端接口硝全,再根據(jù)返回的數(shù)據(jù)進(jìn)行翻轉(zhuǎn)顯示)。

紙牌翻轉(zhuǎn)
<div id="box" class="box viewport-flip">
    <a href="javascript:;" class="list flip in"><div class="img img-before"></div></a>
    <a href="javascript:;" class="list flip out"><div class="img img-back"></div></a>
</div>

關(guān)鍵css代碼

.in{animation-timing-function:ease-out;animation-duration:350ms}
.out{animation-timing-function:ease-in;animation-duration:225ms}
.viewport-flip{-webkit-perspective:1000;perspective:1000;position:absolute}
.flip{backface-visibility:hidden;transform:translateX(0)}
.flip.out{transform:rotateY(-90deg) scale(.9);animation-name:flipouttoleft;animation-duration:175ms}
.flip.in{animation-name:flipintoright;animation-duration:225ms}
@keyframes flipouttoleft {
    from {transform: rotateY(0);}
    to {transform: rotateY(-90deg) scale(.9);}
}
@keyframes flipintoright {
    from {transform: rotateY(90deg) scale(.9);}
    to {transform: rotateY(0);}
}

紙牌翻轉(zhuǎn)楞抡,通過 animation-name 來選擇不同的 keyframes 規(guī)則:點擊翻轉(zhuǎn)的時候設(shè)置頂部的容器為 animation-name: flipouttoleft伟众,底部的容器為 animation-name: flipintoright,來調(diào)用不同規(guī)則達(dá)到翻轉(zhuǎn)抽獎效果召廷;再次點擊凳厢,則效果相反(可以相當(dāng)于重新洗牌);紙牌翻轉(zhuǎn)不僅可以用在抽獎竞慢,也可以用在一些內(nèi)容介紹方面先紫、翻書效果等等,可以根據(jù)項目需要筹煮,開發(fā)出適用于項目的效果遮精。

翻書效果:就是做一個樣式 .pape,再通過關(guān)鍵幀規(guī)則 keyframes寺谤,設(shè)置 rotateY 動畫仑鸥,如下代碼所示:

@keyframes flip-to-left {
    from {transform: rotateY(0);}
    to {transform: rotateY(-180deg);}
}
.pape {
    transform-origin: left center;
    animation: flip-to-left 2s ease-in-out;
}

教你輕松使用css實現(xiàn)滾動列表

活動專題中經(jīng)常有獲獎列表名單的顯示滾動等等,由于列表內(nèi)容比較多变屁,經(jīng)常會用到滾動的方式來展示眼俊,看一下用純 css 實現(xiàn)的滾動效果。

滾動列表
<div class="roll" id="roll">
    <ul>
        <li><span>06-09</span>[新聞]【重要公告】6月15日版本更新</li>
        <li><span>05-28</span>[新聞]【合服公告】6月9日合服公告</li>
        <li><span>05-25</span>[新聞]【重要公告】5月29日版本更新</li>
        <li><span>05-24</span>[新聞]【合服公告】5月26日合服公告</li>
        <li><span>05-24</span>[新聞]【合服公告】5月25日合服公告</li>
        <li><span>05-14</span>[新聞]【重要公告】5月15日版本更新</li>
        <li><span>05-12</span>[新聞]【合服公告】5月12日合服公告</li>
        <li><span>05-11</span>[新聞]【合服公告】5月10日合服公告</li>
        <li><span>06-09</span>[新聞]【重要公告】6月15日版本更新</li>
        <li><span>05-28</span>[新聞]【合服公告】6月9日合服公告</li>
    </ul>
</div>

關(guān)鍵css代碼

.roll ul {
    list-style: none;
    animation: rollList 5s linear infinite;
}
@keyframes rollList {
    0% {margin-top: 0;}
    12.5% {margin-top: 0;}
    25% {margin-top: -40px;}
    37.5% {margin-top: -40px;}
    50% {margin-top: -80px;}
    62.5% {margin-top: -80px;}
    75% {margin-top: -120px;}
    87.5% {margin-top: -120px;}
    100% {margin-top: -160px;}
}

既然我們可以用 css 來實現(xiàn)列表的滾動粟关,那也就是可以用實現(xiàn)圖片的輪播滾動疮胖,在移動端越來越普及的現(xiàn)在,幾句 css 代碼實現(xiàn)闷板,通過設(shè)置 animation-iteration-countinfinite 澎灸,再設(shè)置 keyframes 規(guī)則,來達(dá)到圖片輪播滾動的效果:

img {
    animation: move 8s linear infinite normal;
    animation-fill-mode: forwards;
}
@keyframes move {
    0%{transform: translateX(0px);}
    100%{transform: translateX(-2400px);}
}

一個【開始游戲】動畫的時代變遷

石器時代遮晚,官網(wǎng)開始游戲的動畫效果都是通過 flash 的方式來進(jìn)行交互性昭,美術(shù)大佬寫 flash 動畫交互,前端小哥提供跳轉(zhuǎn)鏈接县遣,感覺天衣無縫糜颠;但是,運營大佬說這個跳轉(zhuǎn)鏈接要改一下萧求,美術(shù)大佬又要重新改 flash其兴,導(dǎo)致這中間的流程非常的繁瑣。
flash 制作的開始游戲按鈕夸政,可維護(hù)性也比較差元旬,也會增加頁面內(nèi)容的大小和請求,影響頁面加載守问。

css3時代匀归,人類在進(jìn)步,技術(shù)也在進(jìn)步酪碘。前端小哥一個人就可以包辦一切朋譬,從內(nèi)容到動畫到跳轉(zhuǎn),一個簡單的官網(wǎng)開始游戲的動畫簡直是信手拈來兴垦,穩(wěn)穩(wěn)的提高了效率徙赢。

用animation制作開始游戲動畫
<a class="start icon-start" href="#" target="_blank"><span></span></a>

關(guān)鍵css代碼

.start:hover span{animation:linear icoBig 1.6s infinite;}
.start:hover span:after{opacity:.6;animation:linear icoBig2 1.6s infinite;}
@keyframes icoBig{
    0%{transform:scale(1)}
    20%{transform:scale(1.05)}
    30%{transform:scale(.93)}
    45%{transform:scale(1.04)}
    60%{transform:scale(1)}
}
@keyframes icoBig2{
    0%{transform:scale(1)}
    20%{transform:scale(1.3);opacity:0}
    100%{transform:scale(1);opacity:0}
}

so easy,上面這段代碼實現(xiàn)了一個開始游戲按鈕鼠標(biāo)經(jīng)過的動畫效果探越;通過設(shè)置 過渡次數(shù) animation-iteration-countinfinite(無限)狡赐,過渡時間 animation-delay1.6s,過渡方式 animation-timing-functionlinear钦幔,再配合 keyframes 規(guī)則進(jìn)行轉(zhuǎn)換枕屉,在 hover 的時候觸發(fā)效果。

純div+css實現(xiàn)多功能又好玩的進(jìn)度條

項目中我們可能會顯示用戶vip的晉升等級鲤氢,或活動專題記錄用戶領(lǐng)取禮包的天數(shù)進(jìn)度等等搀擂,都可以進(jìn)度條來顯示當(dāng)前的進(jìn)度西潘。或者哨颂,上傳圖片的進(jìn)度喷市,下載圖片的進(jìn),都會用到進(jìn)度條威恼∑沸眨看一下用純 css 的如何模擬進(jìn)度條效果。

1箫措、正常加載效果

使用 animation-fill-mode 設(shè)置為 forwards腹备,再通過 keyframes 規(guī)則把動畫狀態(tài)設(shè)置到最后一幀的狀態(tài),讓整個進(jìn)度條達(dá)到 100%斤蔓。

純css制作進(jìn)度條
div {
    height: 10px;border: 1px solid;
    background: linear-gradient(rgb(0, 255, 157), #0ff);
    background-repeat: no-repeat;
    background-size: 0;
    animation: move 2s linear forwards;
}
@keyframes move {
    100% {background-size: 100%;}
}

2植酥、延遲效果圖

使用 animation-delay 設(shè)置延遲時間,延遲可以為負(fù)數(shù)附迷,延遲表示動畫仿佛開始前就已經(jīng)運行過了那么長時間惧互。
上述進(jìn)度條例子,原動畫用了 2s 是從 0% 加載到 100% 的喇伯。如果設(shè)置延遲為 -1s喊儡。這動畫會從 50% 加載到 100%,仿佛已經(jīng)運行了 1s 一樣:

帶延遲的進(jìn)度條
div {
    height: 10px;border: 1px solid;
    background: linear-gradient(#0ff, #0ff);
    background-repeat: no-repeat;
    background-size: 0;
    animation: move 2s -1s linear forwards;
}

3稻据、暫停效果圖

css 動畫是可以暫停的艾猜。屬性 animation-play-state 表示動畫播放狀態(tài),默認(rèn)值 running 表示播放捻悯, paused 表示暫停(鼠標(biāo)經(jīng)過模擬暫停):

帶暫停的進(jìn)度條
.div3 {
    height: 10px;border: 1px solid;
    background: linear-gradient(#0ff, #0ff);
    background-repeat: no-repeat;
    background-size: 0;
    animation: move 2s linear forwards;
}
.div3:hover {
    animation-play-state: paused;
}
@keyframes move {
    100% {background-size: 100%;}
}

animation-play-state 還可以與負(fù)延遲一起實現(xiàn)特殊的效果匆赃,通過設(shè)置 --percent,來達(dá)到進(jìn)度的顯示今缚,比如進(jìn)度條插件:

.div4 {
    height: 10px;border: 1px solid;
    background: linear-gradient(#0ff, #0ff);
    background-repeat: no-repeat;
    background-size: 0;
    animation: move 100s calc(var(--percent) * -1s) linear paused;
    --percent: 30;
}
@keyframes move {
    100% {background-size: 100%;}
}

結(jié)論

經(jīng)過以上幾個例子的學(xué)習(xí)算柳,大概的了解了 animation 的用法,隨著對 animation 的深入理解姓言,在日常開發(fā)中瞬项,是可以做一些更有有趣的動畫,增加頁面的交互性何荚;你可以看看自己之前用 js 寫的各種動畫囱淋,嘗試著用 animation 進(jìn)行修改,相信你一定會有所收獲的餐塘。

ps:一個不懂的人錘太簡單了妥衣,吹牛的永遠(yuǎn)不累

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子税手,更是在濱河造成了極大的恐慌蜂筹,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芦倒,死亡現(xiàn)場離奇詭異狂票,居然都是意外死亡,警方通過查閱死者的電腦和手機熙暴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慌盯,“玉大人周霉,你說我怎么就攤上這事⊙窃恚” “怎么了俱箱?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長灭必。 經(jīng)常有香客問我狞谱,道長,這世上最難降的妖魔是什么禁漓? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任跟衅,我火速辦了婚禮,結(jié)果婚禮上播歼,老公的妹妹穿的比我還像新娘伶跷。我一直安慰自己,他們只是感情好秘狞,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布叭莫。 她就那樣靜靜地躺著,像睡著了一般烁试。 火紅的嫁衣襯著肌膚如雪雇初。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天减响,我揣著相機與錄音靖诗,去河邊找鬼。 笑死辩蛋,一個胖子當(dāng)著我的面吹牛呻畸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悼院,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼伤为,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起绞愚,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤叙甸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后位衩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裆蒸,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年糖驴,在試婚紗的時候發(fā)現(xiàn)自己被綠了僚祷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡贮缕,死狀恐怖辙谜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情感昼,我是刑警寧澤装哆,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站定嗓,受9級特大地震影響蜕琴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宵溅,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一凌简、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恃逻,春花似錦号醉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至润绵,卻和暖如春线椰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尘盼。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工憨愉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卿捎。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓配紫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親午阵。 傳聞我的和親對象是個殘疾皇子躺孝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348