avalon2實際上沒有實現完整的動畫模塊,它只是對現有的CSS3動畫或jquery animate再包裝一層。javascript
咱們先說如何用CSS3爲avalon實現動畫效果。首先要使用avalon.effect註冊一個特效。css
avalon.effect(name, definition)
全部註冊了的特效,均可以在avalon.effects對象中找到。html
css3動畫要求咱們至少添加4個類名。這個是從angular那裏學過來的。所以如何你之前的項目是基於angular,它那些CSS動畫類能夠原封不動地搬過來用。java
avalon.effect('animate', { enterClass: 'animate-enter', enterActiveClass: 'animate-enter-active', leaveClass: 'animate-leave', leaveActiveClass: 'animate-leave-active', })
固然,這些類名會默認幫你添加,由於它內部是這樣實現的。jquery
avalon.effect = function (name, definition) { avalon.effects[name] = definition if (support.css) { if (!definition.enterClass) { definition.enterClass = name + '-enter' } if (!definition.enterActiveClass) { definition.enterActiveClass = definition.enterClass + '-active' } if (!definition.leaveClass) { definition.leaveClass = name + '-leave' } if (!definition.leaveActiveClass) { definition.leaveActiveClass = definition.leaveClass + '-active' } } if (!definition.action) { definition.action = 'enter' } }
所以你能夠簡化成這樣:css3
avalon.effect('animate', {})
註冊完,咱們就須要在樣式表中添加真正的CSS類。web
<style> .animate-enter, .animate-leave{ width:100px; height:100px; background: #29b6f6; transition: width 2s; -moz-transition: width 2s; /* Firefox 4 */ -webkit-transition: width 2s; /* Safari 和 Chrome */ -o-transition: width 2s; /* Opera */ } .animate-enter-active, .animate-leave{ width:300px; } .animate-leave-active{ width:100px; } </style>
咱們還得定義一個vm,裏面指明動畫的動做(默認有三種方式, enter, leave, move)及動畫結束時的回調(這是可選的)css3動畫
var vm = avalon.define({ $id: 'effect', aaa: "test", action: 'enter', enterCb: function(){ avalon.log('動畫完成') }, leaveCb: function(){ avalon.log('動畫回到原點') } })
而後頁面上這樣使用:dom
<div ms-controller='effect' > <div ms-effect="{is:'animate', action:@action,onEnterDone: @enterCb,onLeaveDone: @leaveCb}"> {{@aaa}} </div> <button ms-click='@action = @action !== "leave" ? "leave": "enter"' type="button">click</button> </div>
ms-effect的值爲一個對象,其中is是必選。除了action, 還支持這麼多種回調:動畫
onEnterDone, onLeaveDone, onEnterAbort, onLeaveAbort, onBeforeEnter, onBeforeLeave
若是使用JS實現,則是這樣的:
<!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="../dist/avalon.js"></script> <script src="//cdn.bootcss.com/jquery/3.0.0-beta1/jquery.js"></script> <style> .ani{ width:100px; height:100px; background: #29b6f6; } </style> <script> avalon.effect('animate', { enter: function(el, done){ $(el).animate({width: 300},1000,done) }, leave: function(el, done){ $(el).animate({width: 100},1000,done) } }) var vm = avalon.define({ $id: 'effect', aaa: "test", action: 'enter', enterCb: function(){ avalon.log('動畫完成') }, leaveCb: function(){ avalon.log('動畫回到原點') } }) </script> </head> <body> <div ms-controller='effect' > <div class='ani' ms-effect="{is:'animate', action:@action,onEnterDone: @enterCb,onLeaveDone: @leaveCb}"> {{@aaa}} </div> <button ms-click='@action = @action !== "leave" ? "leave": "enter"' type="button">click</button> </div> </body> </html>
一個CSS3位置效果
<!DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="../dist/avalon.js"></script> <script src="//cdn.bootcss.com/jquery/3.0.0-beta1/jquery.js"></script> <style> .ani{ width:100px; height:100px; background: #ff6e6e; } .wave-enter, .wave-leave { -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s; } .wave-enter { position:absolute; left:45%; } .wave-enter-active { left:0; } .wave-leave { position:absolute; left:0; } .wave-leave-active { left:45%; } </style> <script> avalon.effect('wave', {}) var vm = avalon.define({ $id: 'effect', action: 'enter', enterCb: function () { avalon.log('動畫完成') }, leaveCb: function () { avalon.log('動畫回到原點') } }) </script> </head> <body> <div ms-controller='effect' > <div class='ani' ms-effect="{is:'wave', action:@action,onEnterDone: @enterCb,onLeaveDone: @leaveCb}"> <button ms-click='@action = @action !== "leave" ? "leave": "enter"' type="button">click</button> </div> </div> </body> </html>
ms-widget+ms-for+ms-if+ms-effect的組合動畫效果!
<!DOCTYPE html> <html> <head> <title>ms-if</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> <script src="../dist/avalon.js"></script> <script src="//cdn.bootcss.com/jquery/3.0.0-beta1/jquery.js"></script> <style> .ani{ width:100px; height:100px; background: #ff6e6e; } </style> <script > avalon.component('ms-button', { template: '<button type="button"><span><slot name="buttonText"></slot></span></button>', defaults: { buttonText: "button" }, soleSlot: 'buttonText' }) avalon.effect('zoom', { enter: function (el, done) { $(el).css({width: 0, height: 0}).animate({ width: 100, height: 100 }, 1000, done) }, leave: function (el, done) { $(el).animate({ width: 0, height: 0 }, 1000, done) } }) var vm = avalon.define({ $id: "test", arr: [1,2,3], aaa: 222, toggle: true }) </script> </head> <body ms-controller="test" > <div ms-for="el in @arr"> <div class='ani' ms-attr="{eee:el}" ms-if="@toggle" ms-widget='{is:"ms-button"}' ms-effect="{is:'zoom'}">{{@aaa}}::{{el}}</div> </div> </body> </html>
最後看一下ms-for與stagger的動畫效果。此次爲了與angular一次,stagger應該爲一個小數,它會讓當前元素延遲stagger秒執行。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="../dist/avalon.js"></script> <style> .my-repeat-animation { width: 400px; height: 30px; -webkit-animation-duration: 1s; animation-duration: 1s; } .ng-enter { -webkit-animation-name: enter_animation; animation-name: enter_animation; } .ng-enter-stagger { animation-delay:300ms; -webkit-animation-delay:300ms; } .ng-leave { -webkit-animation-name: leave_animation; animation-name: leave_animation; } @keyframes enter_animation { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes leave_animation { from { opacity: 1; } to { opacity: 0; } } @-webkit-keyframes enter_animation { from { opacity: 0; } to { opacity: 1; } } @-webkit-keyframes leave_animation { from { opacity: 1; } to { opacity: 0; } } </style> <script> avalon.effect("my-repeat-animation", { enterClass: "ng-enter", leaveClass: "ng-leave" }) var vm = avalon.define({ $id: "test", array: [1, 2, 3, 4], getBg: function() { return '#' + Math.floor(Math.random() * 16777215).toString(16); }, add: function() { vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) vm.array.push(vm.array.length + 1) }, value: "" }) vm.$watch("value", function(a) { if (a) { vm.array.removeAll(function(el) { return el !== a }) } else { if(vm.array.length < 12) vm.add() } }) </script> </head> <body ms-controller="test"> <button ms-click="@add">Add</button> <input placeholder="只保留" ms-duplex-number="@value" /> <div class="my-repeat-animation" ms-for="item in @array" ms-css="{background:@getBg()}" ms-effect="{is:'my-repeat-animation',stagger:0.3}"> {{item}} </div> </body> </html>
目前,avalon的ms-effect能夠與ms-visible,ms-if,ms-repeat連用。ms-effect也能夠單獨或與其餘指令使用,這時須要你指定action。
<div ms-effect="{is:"effectName", action: @action}">