以往,想在HTML上實現動畫效果,要不就用被喬布斯恨死的了Flash 動畫,要不就用網頁動畫圖像或者JavaScript 實現效果。在CSS3之后,就可以用CSS在HTML上實現動畫了。
要創(chuàng)建 CSS3 動畫,你需要了解 @keyframes 規(guī)則?,F在 @keyframes 創(chuàng)建動畫時,需將其綁定到一個選擇器,否則動畫不會有任何效果。
用CSS3原生代碼創(chuàng)建動畫,語法是@keyframes animationname {keyframes-selector {css-styles;}},其中animationname :必需,動畫的名稱;
keyframes-selector:必需,動畫時長的百分比合法的值:0-100%, from(與 0% 相同),to(與 100% 相同)
css-styles:必需,一個或多個合法的 CSS 樣式屬性。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>動起來</title>
<style>
div {
width: 100px;
height: 100px;
background: red;
position: relative;
animation: myfirst 5s;
-webkit-animation: firstan 5s; /* Safari and Chrome */
}
@keyframes firstan {
0% {
background: red;
left: 0px;
top: 0px;
}
25% {
background: yellow;
left: 200px;
top: 0px;
}
50% {
background: blue;
left: 200px;
top: 200px;
}
75% {
background: green;
left: 0px;
top: 200px;
}
100% {
background: red;
left: 0px;
top: 0px;
}
}
@-webkit-keyframes myfirst /* Safari and Chrome */
{
0% {
background: red;
left: 0px;
top: 0px;
}
25% {
background: yellow;
left: 200px;
top: 0px;
}
50% {
background: blue;
left: 200px;
top: 200px;
}
75% {
background: green;
left: 0px;
top: 200px;
}
100% {
background: red;
left: 0px;
top: 0px;
}
}
</style>
</head>
<body>
<div/>
</body>
</html>
輸出結果
如果每次都要自己手動用CSS去創(chuàng)建動畫,那效果太低了。為此,有人專門專門開發(fā)了CSS動畫庫animation.css。可以在線https://animate.stylek看效果,它里面的動畫效果,可以滿足大多數需求了。下載https://github.com/animate-css/animate.css里的animate.min.css文件,放到HTML文件相同目錄下。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用動畫庫實現動畫</title>
<link rel="stylesheet" type="text/css" href="animate.min.css"/>
</head>
<body>
<main class="animate__animated animate__fadeInLeft">
老陳說編程,動畫效果行
</main>
</body>
</html>
輸出結果
好了,有關CSS動畫效果的內容,老陳講完了,如果覺得對你有所幫助,希望老鐵能轉發(fā)點贊,讓更多的人看到這篇文章。你的轉發(fā)和點贊,就是對老陳繼續(xù)創(chuàng)作和分享最大的鼓勵。
一個當了10年技術總監(jiān)的老家伙,分享多年的編程經驗。想學編程的朋友,可關注:老陳說編程。分享Python,前端(小程序)、App和嵌入式方面的干貨。關注我,沒錯的。
#前端##HTML5##CSS##程序員##Web#
渡效果在交互體驗中的重要性不言而喻。以往我們使用jQuery添加或移除元素的類,搭配CSS中定義好的樣式,再引用一些JavaScript庫之后,可以做出非常復雜、驚艷的動態(tài)效果,不過這一套方法仍略顯煩瑣。Vue.js內置了一套過渡系統,可以在元素從 DOM中插入或移除時自動應用過渡效果。Vue.,js會在適當的時機觸發(fā)CSS 過渡或動畫,用戶也可以提供相應的JavaScript鉤子函數在過渡過程中執(zhí)行自定義DOM操作。
過渡效果就是在DOM元素進行切換、隱藏、插入和移除的時候加入一些酷炫的效果,使得過渡更加自然和美觀,那么要想讓組件實現動畫,最基礎的做法就是:
應用過渡效果,在需要加動畫的地方,加入transition標簽。代碼示例如下:
<div id="app">
<transition>
<div v-if="show"></div>
</transition>
</div>
transition特性可以與以下資源一起搭配使用:
我們先來看個簡單基礎的動畫案例,大家看案例代碼:
例8-1 Demo0801.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>動畫</title>
<!-- 在線引入vue.js,必須引入否則無法使用vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
#app {
text-align: center;
}
#app div {
width: 200px;
height: 200px;
margin: 30px auto;
background-color: bisque;
border: 1px solid bisque;
}
/* 進入和離開的狀態(tài) */
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s;
}
/* .fade-enter定義進入過渡的開始狀態(tài) */
/* .fade-leave-to定義離開后的狀態(tài) */
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">切換</button>
<br>
<transition name="fade">
<div v-if="show"></div>
</transition>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
show: true
},
})
</script>
</html>
程序的運行結果如下:
圖 8- 1 入門案例
點擊切換按鈕,我們看到div框有一個淡入淡出的效果,原理如下:
當插入或刪除包含在 transition 組件中的元素時,Vue 將會做以下處理:
在案例中我們使用到了一些過渡的類名,現在來看看,在元素在進入/離開的過渡中,會有 6 個 class 切換。
圖 8- 2 過渡類名
特別說明,對于這些在過渡中切換的類名來說,如果你使用一個沒有名字的 <transition>,則 v- 是這些類名的默認前綴。如果你使用了 <transition name="my-transition">,那么 v-enter 會替換為 my-transition-enter。
我們常用的過渡都是使用 CSS 的樣式規(guī)則實現過渡,借助css的樣式實現酷炫的過渡效果。
我們來看8-2案例代碼:
例8-2 Demo0802.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>動畫</title>
<!-- 在線引入vue.js,必須引入否則無法使用vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
#app {
text-align: center;
}
#app div {
width: 200px;
height: 200px;
margin: 30px auto;
background-color: bisque;
border: 1px solid bisque;
}
/* 可以設置不同的進入和離開動畫 */
/* 設置持續(xù)時間和動畫函數 */
.fade-enter-active {
transition: all .3s ease;
}
.fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.fade-enter,
.fade-leave-to {
transform: translateX(160px);
opacity: 0;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">切換</button>
<br>
<transition name="fade">
<div v-if="show"></div>
</transition>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
show: true
},
})
</script>
</html>
程序的運行結果跟例子8-1的區(qū)別是在水平位置上的偏移實現了平滑的過渡。我們可以借鑒之前學習的transform屬性,靈活使用,還可以加入更多的樣式規(guī)則,實現想要的效果。
在這我們需要注意,入場類名有三個:
<name>-enter:入場前
<name>-enter-active:入場持續(xù)的過程
<name>-enter-to:入場的結束
出場類名有三個:
<name>-leave:出場前
<name>-leave-active:出場持續(xù)的過程
<name>-leave-to:出場的結束
在上一小節(jié)中,我們初步了解了Vue使用transition標簽實現過渡的效果,接下來我們來看看具體的實現過程,以及原理。
首先,我們來看以下代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>動畫</title>
<!-- 在線引入vue.js,必須引入否則無法使用vue-->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
#app {
text-align: center;
}
#app div {
width: 200px;
height: 200px;
margin: 30px auto;
background-color: bisque;
border: 1px solid bisque;
}
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">顯示/隱藏</button>
<br>
<transition name="fade">
<div v-if="show"></div>
</transition>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
show: false
},
})
</script>
</html>
上面的代碼我們只定義了進入前的類,以及進入的持續(xù)過程,我們通過過程看原理:
當動畫執(zhí)行的一瞬間,會在內部的div上增加兩個class名字,分別是fade-enter和fade-enter-active,之所以是fade-開頭,是因為transiton標簽name是fade。當動畫運行到第二幀的時候,Vue又會幫助你把fade-enter刪除,然后添加一個fade-enter-to,再當動畫執(zhí)行到結束的一瞬間,又把fade-enter-active和fade-enter-to刪除掉。
注意,在第一幀的時候,fade-enter-active和fade-enter同時存在,并且opacity=0,在第二幀的時候,fade-enter被刪除,opacity恢復到原來的初始狀態(tài),就是1,在這個過程中,opacity發(fā)生了變化,所以fade-enter-active就讓這個變化在3秒內完成,完成后進入到fade-enter-to的狀態(tài),但是我們沒有定義則默認就是過程持續(xù)后的狀態(tài),opacity為1,此時進入的過渡狀態(tài)已經完成,刪除fade-enter-to和fade-enter-active,這就是元素進入的一個完整的過程。
但是如果要加入fade-enter-to,需要注意下圖所示:
如果初始定義中沒有加寬和高,則進入動畫完成后,該div就會消失,所以最好在這定義好div的樣式規(guī)則
width height
如果想要某個樣式規(guī)則在過渡中有效果,就必須寫在<name>-enter中也加入,不能只在#app div的初步定義中寫,否則在接下來的active和enter-to中則無效。
以上講解入場的過程原理,接下來看出場的過程原理:
加入以下代碼:
#app {
text-align: center;
}
#app div {
margin: 30px auto;
background-color: bisque;
width: 200px;
height: 200px;
}
.fade-enter {
opacity: 0;
width: 200px;
height: 200px;
}
.fade-enter-active {
transition: opacity 1s, width 1s, height 1s;
}
.fade-enter-to {
border: 1px solid red;
width: 100px;
height: 100px;
}
.fade-leave {
opacity: 0.5;
width: 50px;
height: 50px;
}
.fade-leave-active {
transition: opacity 2s, width 2s, height 2s;
}
.fade-leave-to {
opacity: 0;
width: 200px;
height: 200px;
}
我們發(fā)現,進入效果完成后,我們定義了離開過渡的開始狀態(tài)fade-leave,在data中show的值為false時,開始離開,此時會為類加上fade-leave和fade-leave-active狀態(tài),離開的持續(xù)過程完成后,進入結束狀態(tài)fade-leave-to,此時fade-leave已經被刪除,出場完成后,fade-leave-active和fade-leave-to被刪除。
整個過程總結如下:
【v-enter】
定義進入過渡的開始狀態(tài)。在元素被插入時生效,在下一個幀移除
【v-enter-active】
定義過渡的狀態(tài)。在元素整個過渡過程中作用,在元素被插入時生效,在 transition 或 animation 完成之后移除。 這個類可以被用來定義過渡的過程時間,延遲和曲線函數
【v-enter-to】
定義進入過渡的結束狀態(tài)。在元素被插入一幀后生效(與此同時 v-enter 被刪除),在 transition 或 animation 完成之后移除
【v-leave】
定義離開過渡的開始狀態(tài)。在離開過渡被觸發(fā)時生效,在下一個幀移除
【v-leave-active】
定義過渡的狀態(tài)。在元素整個過渡過程中作用,在離開過渡被觸發(fā)后立即生效,在 transition 或 animation 完成之后移除。 這個類可以被用來定義過渡的過程時間,延遲和曲線函數
【v-leave-to】
定義離開過渡的結束狀態(tài)。在離開過渡被觸發(fā)一幀后生效(與此同時 v-leave 被刪除),在 transition 或 animation 完成之后移除
以上就是我們整個過渡的過程和原理,接下來我們來看動畫。
上一小節(jié),我們實現了CSS過渡,通常過渡使用的是transition,本節(jié)課我們使用animation來加入動畫效果。
例8-3 Demo0803.html
圖 8- 4 顯示效果
例8-3中我們使用了animation給div進入和離開分別設置了縮放的動畫效果,也可以借助之前學習的animation的知識實現更多酷炫的效果。
Vue 為了知道過渡的完成,必須設置相應的事件監(jiān)聽器。它可以是 transitionend 或 animationend ,這取決于給元素應用的 CSS 規(guī)則。如果使用其中任何一種,Vue 能自動識別類型并設置監(jiān)聽。
但是,在一些場景中,需要給同一個元素同時設置兩種過渡動效,比如 animation 很快的被觸發(fā)并完成了,而 transition 效果還沒結束。在這種情況中,就需要使用 type 特性并設置 animation 或 transition 來明確聲明需要 Vue 監(jiān)聽的類型,我們來看下面的案例:
例8-4 Demo0804.html
通過以上案例,我們發(fā)現如何設置type=‘transition’則主要是監(jiān)聽過渡為主,動畫則不會執(zhí)行1.5倍的縮放,因為過渡1s就完成了。如果type=’animation’則以監(jiān)聽動畫為主,就會完整的執(zhí)行動畫,這一點大家在混合使用的時候注意。
我們可以通過以下 attribute 來自定義過渡類名:
他們的優(yōu)先級高于普通的類名,這對于 Vue 的過渡系統和其他第三方 CSS 動畫庫,如 Animate.css 結合使用十分有用。
使用animate的步驟:
第一步:下載
https://daneden.github.io/animate.css
第二步:引入
在線引入:
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
本地引入:
<link href="./animate.min.css" rel="stylesheet" type="text/css"/>
例8-5 Demo0805.html
至此,便可以實現vue+animate.css動畫庫的結合使用。它的優(yōu)勢,像某些比較復雜的動畫效果,此時便省去手寫過程,直接引入使用現有動畫庫即可,大大提高了開發(fā)效率。
注意:
1、必須使用transition標簽的自定義動畫名屬性,即enter-active-class和leave-active-class;
2、使用時必須加入animated類名。
如果想在頁面初始化時渲染動畫效果,此時需要用到appear呈現屬性和appear-active-class呈現過渡屬性,語法如下:
<transition appear>
<!-- ... -->
</transition>
如果只寫appear,則初始化動畫默認和進入/離開過渡效果一樣,同樣也可以自定義 CSS 類名。
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" (2.1.8+)
appear-active-class="custom-appear-active-class"
>
<!-- ... -->
</transition>
但是要注意,它只是在第一次渲染的時候才會起作用。
例8-6 Demo0806.html
例8-6中,在頁面初始化時候是沒有動畫效果的,點擊按鈕的時候才會觸發(fā)動畫;如果想要在頁面初始化就有動畫效果,就必須加appear,也可以指定初始化動畫,如下示例:
<div id="app">
<transition appear appear-class="animated shakeY" appear-to-class="animated wobble"
appear-active-class="animated jello" name="fade" enter-active-class="animated swing fade-enter-active"
leave-active-class="animated swing fade-leave-active">
<div v-show="show">
我是要顯示的內容
</div>
</transition>
<button @click="show=!show">點擊</button>
</div>
但是這里有一些問題:關于appear-class、 appear-to-class、 appear-active-class的相同屬性那個起作用的問題。
四種情況:(與他們在style中的排列順序有關系)
1、appear-class、 appear-to-class、 appear-active-class或者 appear-to-class、appear-class、 appear-active-class的排列順序,此時只有appear-active-class的屬性起作用。
2、appear-active-class、appear-class、 appear-to-class
此時appear-active-class的不起作用,由appear-class過渡到appear-to-class屬性。
3、appear-class、appear-active-class、 appear-to-class
此時appear-class屬性不起作用,由appear-active-class過渡到 appear-to-class屬性。
4、 appear-to-class、 appear-active-class、appear-class
此時appear-to-class不起作用,由appear-class過渡到 appear-active-class屬性。
在很多情況下,Vue 可以自動得出過渡效果的完成時機。默認情況下,Vue 會等待其在過渡效果的根元素的第一個 transitionend 或 animationend 事件。然而也可以不這樣設定——比如,我們可以擁有一個精心編排的一系列過渡效果,其中一些嵌套的內部元素相比于過渡效果的根元素有延遲的或更長的過渡效果。
在這種情況下你可以用 <transition> 組件上的 duration prop 定制一個顯性的過渡持續(xù)時間 (以毫秒計):
<transition :duration="1000">...</transition>
你也可以定制進入和移出的持續(xù)時間:
<transition :duration="{ enter: 500, leave: 800 }">
...
</transition>
上一節(jié)我們使用CSS實現的過渡和動畫,本節(jié)課講解使用JavaScript鉤子函數實現過渡和動畫。
JavaScript鉤子函數完整過程如下:
before-enter:進入過渡前;
enter:過渡運行時;
after-enter:過渡完成后;
enter-cancelled:過渡被打斷;
before-leave:離開過渡運行前;
leave:離開過渡運行時;
after-leave:離開過渡運行后;
leave-cancelled:離開過渡被打斷;
使用示例代碼:
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
/ ...
methods: {
// --------
// 進入中
// --------
beforeEnter: function (el) {
// ...
},
// 當與 CSS 結合使用時
// 回調函數 done 是可選的
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 離開時
// --------
beforeLeave: function (el) {
// ...
},
// 當與 CSS 結合使用時
// 回調函數 done 是可選的
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
接下來我們來一個一個的看:
示例代碼:
<style>
#app div {
width: 200px;
height: 200px;
background-color: antiquewhite;
}
</style>
</head>
<body>
<div id="app">
<transition @before-enter="beforEnter">
<div v-show="show">
我是要顯示的內容
</div>
</transition>
<button @click="show=!show">點擊</button>
</div>
</body>
<script>
var count = 0;
new Vue({
el: '#app',
data: {
show: true
},
methods: {
//進入過度前把dom元素設置為字體為紅色
beforEnter(el) {
console.log('beforEnter觸發(fā)了');
el.style.color = "red";
}
}
})
</script>
程序運行效果如下:
圖 8- 5 入場前過渡
該示例代碼中鉤子函數參數el指的時過渡的元素div,給div設置過渡前的樣式。
enter鉤子和before-enter稍微有些差異,enter會接受兩個參數,語法為enter(el,done),done為回調函數。當before-enter觸發(fā)完畢后的下一幀,將會真正運行動畫效果,整個動畫效果也將放到enter這個鉤子階段。
案例:2s后元素字體顏色有紅色編程藍色
示例代碼:
<div id="app">
<transition @before-enter="beforEnter" @enter="enterFun">
<div v-show="show">
我是要顯示的內容
</div>
</transition>
<button @click="show=!show">點擊</button>
</div>
enterFun(el, done) {
setInterval(() => {
el.style.color = "blue";
}, 2000);
done();//告知動畫結束
}
執(zhí)行時機,在enter過渡進入完成后觸發(fā)done()回調函數,告知vue動畫執(zhí)行完畢,下一步執(zhí)行after-enter過渡完成后鉤子函數。
示例代碼:
<body>
<div id="app">
<transition @before-enter="beforEnter" @enter="enterFun" @after-enter="afterFn">
<div v-show="show">
我是要顯示的內容
</div>
</transition>
<button @click="show=!show">點擊</button>
</div>
</body>
<script>
var count = 0;
new Vue({
el: '#app',
data: {
show: true
},
methods: {
//進入過度前把dom元素設置為字體為紅色
beforEnter(el) {
console.log('beforEnter觸發(fā)了');
el.style.color = "red";
},
enterFun(el, done) {
setTimeout(() => {
el.style.color = "blue";
}, 2000);
setTimeout(() => {
done();//告知動畫結束后才會調用下一幀的afterFn
}, 4000);
},
afterFn(el) {
el.style.color = "purple";
}
}
})
</script>
示例代碼:
<div id="app">
<transition @before-enter="beforEnter" @enter="enterFun" @after-enter="afterFn" @enter-cancelled="calFn">
<div v-show="show">
我是要顯示的內容
</div>
</transition>
<button @click="show=!show">點擊</button>
</div>
calFn() {
console.log('calFn');
}
當過渡開始的時候,不等過渡執(zhí)行完畢,打斷過渡就會執(zhí)行enter-cancelled。
出場鉤子與入場鉤子語法類似,如下:
1、before-leave(el)離開過渡運行前
2、leave(el,done)離開過渡運行時
3、after-leave(el)離開過渡運行后
4、leave-cancelled(el)離開過渡被打斷時
注意:leave和enter一樣,接受兩個參數,而且要執(zhí)行下一幀,必須顯示調用done().
如果transition 中包含多個元素,我們來看如何設置:
樣式部分設置:
Html結構部分:
Script部分:
以上案例中,要注意,transition中如果多個元素切換,則必須使用key,避免復用。
mode是transition自帶的屬性,可以是out-in(先出后進) 或者 in-out(先進后出)。
在上一節(jié)中,transition中有多個html元素,如果transition中有多個自定義組件時候該如何過渡呢,我們看以下代碼:
樣式部分設置:
Html結構部分:
Script部分:
該案例中,我們使用動態(tài)組件實現切換,其實跟多元素本質是一樣的。
如果transition中同時有多個元素或者組件,我們應該使用transition-group,接下來我們來看案例:
例8-6 Demo0806.html
圖 8- 6 列表效果
在該案例中,我們發(fā)現每添加一條數據,都有動畫過渡。如果使用v-for,并且循環(huán)的每個列表在添加和移除的時候需要設置過渡和動畫則必須使用transition-group。
過渡可以通過 Vue 的組件系統實現復用。我們可以把一個封裝好動畫的組件,實現在任何頁面的復用。
下面我們來看步驟:
第一步:過渡組件建立:
Vue.component('my-special-transition', {
template: `
<transition name="very-special-transition" mode="out-in" v-on:before-enter="beforeEnter" @enter="enterFn"
v-on:after-enter="afterEnter">
<slot v-if='status'></slot>
</transition>
`,
props: ['status'],
methods: {
beforeEnter: function (el) {
el.style.color = "red";
},
enterFn(el, done) {
setTimeout(() => {
el.style.color = 'green';
}, 2000);
setTimeout(() => {
done();
}, 4000);
},
afterEnter: function (el) {
el.style.color = "blue";
}
}
})
在這我們使用的插槽,因為不確定我們要過渡的內容,在slot上加上v-if=’status’,這個status的值是從根組件上傳過來的。
第二步:調用
示例代碼:
<div id="app">
<button @click="show = !show">切換</button>
<my-special-transition :status="show">
<p>世界,你好</p>
</my-special-transition>
</div>
完整代碼:
<body>
<div id="app">
<button @click="show = !show">切換</button>
<my-special-transition :status="show">
<p>世界,你好</p>
</my-special-transition>
</div>
<script>
Vue.component('my-special-transition', {
template: `
<transition name="very-special-transition" mode="out-in" v-on:before-enter="beforeEnter" @enter="enterFn"
v-on:after-enter="afterEnter">
<slot v-if='status'></slot>
</transition>
`,
props: ['status'],
methods: {
beforeEnter: function (el) {
el.style.color = "red";
},
enterFn(el, done) {
setTimeout(() => {
el.style.color = 'green';
}, 2000);
setTimeout(() => {
done();
}, 4000);
},
afterEnter: function (el) {
el.style.color = "blue";
}
}
})
new Vue({
el: '#app',
data: {
show: false
}
});
</script>
總結:復用過渡組件主要是借助于父子組件的傳值。
下面我們來使用學習的過渡動畫實現一個簡單的小案例:
目標:
例8-7 Demo0807.html
程序運行效果如下:
圖 8- 7 過渡效果
本案例,在添加的時候設置了過渡效果,在點擊每一條的時候實現過渡刪除每一條目;核心代碼主要是使用列表過渡。
在圖書管理系統的基礎上:
天我們學習的內容有:過渡,動畫,轉換,伸縮盒子。
可以說今天學習的內容都是重量級的大佬,學好了,使用css3做出酷炫的效果 So Easy!~~
1.過渡
在css3中,有一個屬性可以設置過渡效果。
它就是transition,所謂的過渡效果,指的就是以動畫的形式慢慢演化樣式屬性變化的過程。
A.案例:通過transition設置焦點過渡效果
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>div{width: 200px;height: 200px;margin:200px;background: url(girl.jpg);border-radius:50%;transition:all 1s linear 0.3s;cursor: pointer;}div:hover{box-shadow: 0px 0px 20px blue;}</style></head><body><div></div></body></html>
注意頁面中的代碼:
第一,我們給div添加了一個hover偽類樣式,當我們鼠標懸停在div上方的時候,會給div盒子添加一個藍色的盒子陰影。
第二,我們給div盒子添加了一個transition樣式,設置的值為:all 1s linear 0.3s;
這四個數據分別對應
transition-property(需要過渡的屬性):如果設置為all表示所有樣式屬性都需要過渡。
transition-duration(過渡的時間):以秒作為單位,設置過渡的時間
transition-timing-function(過渡的方式):常用的有l(wèi)inear(勻速),ease(先慢后快),ease-in,ease-out,ease-in-out等
transition-delay(延遲的時間):以秒作為單位進行延遲,延遲之后開始進行過渡效果。
所以,我們通過transition這個復合屬性設置的過渡效果為:
all:需要過渡所有的屬性
1s:過渡的時間為1秒
linear:勻速過渡
0.3s:在延遲0.3秒之后開始過渡動畫。
如果大家理解了上面的描述,那么也就不難理解咱們鼠標放到div上之后,為啥會慢慢出現藍色的光暈了,就是因為咱們添加了過渡,所以,慢慢的就會給盒子添加陰影效果。
2.動畫:
在學習完了過渡之后,發(fā)現咱們可以使用transition去以動畫的形式展示樣式的改變以及變化的過程,這可以幫助我們來實現一些過渡的動畫。
但是,有的時候,我們的需求會更加的復雜,要求會更加的多變,那么,transition可能就無法滿足我們的需要了,我們需要有更加炫酷,復雜的效果呈現。
那么,動畫animation就可以滿足我們的需要。
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>@keyframes moveAndChange{0%{left:0px;top:0px;}25%{left:200px;top:200px;background:green;border-radius: 0;}50%{left:400px;top:200px;background:blue;border-radius: 50%;}75%{left:400px;top:0px;background:#ccc;border-radius: 0;}100%{left:0px;top:0px;background:red;border-radius: 50%;}}div{margin:200px;width: 200px;height: 200px;position: absolute;background:red;border-radius:50%;animation: moveAndChange 5s linear 0.5s infinite normal;}</style></head><body><div></div></body></html>
代碼效果如下:
同樣,讓我們來關注編寫的代碼:
1.在樣式中,首先我們使用@keyframes 來定義了一個復雜的動畫,在css3中,新增了@keyframes可以來幫助我們添加動畫。代碼如下:
/*動畫的名字叫做moveAndChange*/
@keyframes moveAndChange{
/*動畫最初的時候,將left設置為0px,top設置為0px*/
0%{
left:0px;
top:0px;
}
/*當動畫進行到25%的時候,使用動畫將left過渡到200px,top過渡到200px,
背景顏色過渡為綠色,圓角過渡為0(無圓角)*/
25%{
left:200px;
top:200px;
background:green;
border-radius: 0;
}
/*當動畫進行到50%的時候,使用動畫將left過渡到400px,top過渡到200px,
背景顏色過渡為藍色,圓角過渡為50%(正圓)*/
50%{
left:400px;
top:200px;
background:blue;
border-radius: 50%;
}
/*當動畫進行到75%的時候,使用動畫將left過渡到400px,top過渡到0,
背景顏色過渡為灰色,圓角過渡為0(無圓角)*/
75%{
left:400px;
top:0px;
background:#ccc;
border-radius: 0;
}
/*當動畫結束的時候,使用動畫將left過渡到0x,top過渡到0px,
背景顏色過渡為紅色,圓角過渡為50%(正圓)*/
100%{
left:0px;
top:0px;
background:red;
border-radius: 50%;
}
}
這是一個比較復雜的動畫效果,可以發(fā)現,它通過百分比的形式將一個完整的動畫拆分成了5個部分,每個部分都有不同的樣式效果,而當我們采用該動畫的元素就會按照設置的順序和樣式效果進行動畫的過渡和展示。
2.上面我們只是通過@keyframes創(chuàng)建了一個動畫,我們還需要通過特定的語法來使用這個動畫。
就是下面這句代碼了:
animation: moveAndChange 5s linear 0.5s infinite normal;
它是一個復合屬性,設置了6個值,分別對應:
animation-name(設置動畫的名稱):用來設置動畫的名字,我們這里寫的是moveAndChange ,也就是說我們就是要使用我們剛剛創(chuàng)建的動畫。
animation-duration(設置整個動畫的時間):以秒作為單位,我們這里寫的是5s,表示整個動畫的時間為5秒
animation-timing-function(設置播放動畫的方式):播放動畫的方式,常用的有l(wèi)inear(勻速),ease(先慢后快),ease-in,ease-out,ease-in-out等,我們使用的是linear勻速播放動畫。
animation-delay(設置動畫的延遲):以秒作為單位,我們寫的是0.5s,表示延遲0.5秒之后開始播放動畫。
animation-iteration-count(設置動畫播放的次數):播放動畫的次數,我們這里寫的是infinite ,表示動畫將會被播放無限次,如果寫數字,那么就會播放數字對應的次數。
animation-direction(設置是否反向播放動畫):我們寫的是normal,表示正常播放動畫,如果寫的是
alternate則表示要反向播放動畫,大家也可以自己試一試這個效果。
最終,我們通過@keyframes創(chuàng)建動畫,通過animation設置動畫,成功完成了這個復雜的動畫效果。
3.轉換
在css3中,我們通過transform屬性可以設置元素的轉換效果,具體的效果如下:
A.平移
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>body{background:pink;}div{width: 200px;height: 200px;position: absolute;background: green;left:0px;top:0px;transform: translate(300px,300px);}</style></head><body><div></div></body></html>
代碼效果如下:
如上圖所示,本來div盒子的位置是left:0,top:0;
但是我們通過transform: translate(300px,300px);將盒子進行了偏移,所以,盒子的位置發(fā)生了改變。
B.旋轉
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>body {background: pink;}div {width: 200px;height: 200px;margin: 200px;position: absolute;background: green;left: 0px;top: 0px;transform: rotate(45deg);}</style></head><body><div></div></body></html>
代碼效果如下:
如上圖所示,本來div盒子應該是四四方方的。
但是,經過我們的代碼transform: rotate(45deg); //deg為單位,表示度數。
進行了45度的旋轉之后,呈現出來的就是一個菱形的盒子了,旋轉的正方向為順時針,負方向為逆時針。
C.縮放
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>body {background: pink;}div {width: 200px;height: 200px;margin: 200px;position: absolute;background: green;left: 0px;top: 0px;transform: scale(0.5,0.25);}</style></head><body><div></div></body></html>
代碼效果如下:
如上圖所示,本來盒子的寬高為200*200,而我們通過transform: scale(0.5,0.25);進行的縮放
scale的第一個參數為0.5,表示橫向縮小為0.5倍
scale的第二個參數為0.25,表示縱向縮小為0.25倍。
scale的參數如果為1,則表示不進行任何縮放,小于1就是做縮小,而大于1表示做放大。
小結:transform轉換中其實還包含了skew(傾斜),matrix(矩陣轉換),相對來說用到的不是特別多,所以在本文中我們便不再做介紹。
4.flex布局
Flex布局,可以簡便、完整、響應式地實現各種頁面布局。
Flex是Flexible Box的縮寫,翻譯成中文就是“彈性盒子”,用來為盒裝模型提供最大的靈活性。任何一個容器都可以指定為Flex布局。
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>div{box-sizing: border-box;}.parent {width: 600px;height: 200px;margin: 100px;position: absolute;background: green;left: 0px;top: 0px;display: flex;justify-content: flex-start}.parent div{width: 20%;border:1px solid #ccc;background:pink;}</style></head><body><div><div>1</div><div>2</div><div>3</div><div>4</div></div></body></html>
代碼效果如下:
如圖所示,咱們通過display:flex將.parent元素設置為了flex盒子,那么子元素將會按照justify-content設置的方式進行元素的排列,目前看來,和我們沒有設置flex盒子的效果是一致的。
接下來我們更改一下,將justify-content設置為flex-end,效果如下圖所示:
所以我們就應該發(fā)現,flex-start是讓所有的子元素從父元素的左側開始排列
而flex-end是讓所有的子元素從元素的右側開始排列。
我們再來更改一下,將justify-content設置為center,效果如下圖所示:
更厲害了,子元素在父盒子的中央位置排列顯示了。
然后,我們再將justify-content設置為space-around,效果如下圖所示:
它是平均分配的形式為每一個子元素設置了間距,但是看起來有點變扭。
所以我們推薦將justify-content設置為space-between,效果如下圖:
我們還可以通過flex-wrap來設置子元素是否換行顯示,以及flex-direction設置子元素排列的順序。
這兩個屬性可以設置的值如下:
flex-wrap: nowrap;//不換行,會自動收縮
flex-wrap: warp;//換行,會自動收縮
flex-wrap: warp-reverse;//反轉,從默認的從上到下排列反轉為從下到上。
flex-direction:row; //從左至右一行一行進行子元素的排列
flex-direction:column; //從上到下一列一列進行子元素的排列
flex-direction:row-reverse; //從右至左一行一行進行子元素的排列
flex-direction:column-reverse; //從下到上一列一列進行子元素的排列
案例代碼如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>div{box-sizing: border-box;}.parent {width: 600px;height: 200px;margin: 100px;position: absolute;background: green;left: 0px;top: 0px;display: flex;justify-content: space-between;flex-wrap: nowrap;flex-direction: row-reverse;}.parent div{width: 20%;border:1px solid #ccc;background:pink;}</style></head><body><div><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div></div></body></html>
我們設置了flex-wrap: nowrap;(不換行,壓縮所有的子元素在一行中顯示),以及flex-direction: row-reverse;(反向排列)
代碼效果如下:
如果設置為flex-wrap: warp(換行顯示無法在一行顯示的子元素),則效果如下:
如果將flex-direction: column;,則會縱向排列元素,效果如下圖:
除了上面的這些給伸縮盒子父元素設置的樣式之外,我們還可以可以伸縮盒子的子元素設置flex屬性,用來設置平均分配整個父盒子的空間。
代碼如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>div{box-sizing: border-box;}.parent {width: 600px;height: 200px;margin: 100px;position: absolute;background: green;left: 0px;top: 0px;display: flex;justify-content: space-between;}.parent div{flex:1;width: 20%;border:1px solid #ccc;background:pink;}</style></head><body><div><div>1</div><div>2</div><div>3</div><div>4</div></div></body></html>
效果如下:
如上圖所示,每個盒子平均分配了父盒子的空間,原本寬度為20%,現在被拉伸了。
除此之外,咱們還可以使用flex屬性進行進一步的設置,代碼如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Document</title><style>div{box-sizing: border-box;}.parent {width: 600px;height: 200px;margin: 100px;position: absolute;background: green;left: 0px;top: 0px;display: flex;justify-content: space-between;}.parent div:nth-of-type(1){flex:1;border:1px solid #ccc;background:red;}.parent div:nth-of-type(2){flex:2;border:1px solid #ccc;background:green;}.parent div:nth-of-type(3){flex:2;border:1px solid #ccc;background:blue;}.parent div:nth-of-type(4){flex:1;border:1px solid #ccc;background:pink;}</style></head><body><div><div>1</div><div>2</div><div>3</div><div>4</div></div></body></html>
效果如下圖:
我們分別給四個子盒子設置了flex:1 , flex:2, flex:2 ,flex:1.
這是什么意思呢?
四個flex加起來一共是6.那么第一個盒子就占據整個父盒子的1/6寬度。
同理,另外三個盒子分別占據2/6,2/6,1/6的寬度,所以就形成了我們現在看到的效果。
原文來源于:黑馬程序員社區(qū)
學習資源:
想學習css,可以關注:黑馬程序員頭條號,后臺回復:css
*請認真填寫需求信息,我們會在24小時內與您取得聯系。