angular2 学习笔记 ( animation 动画 )

2020-06-03 原生 animation api vs angular animation vs css animation 

refer : 

https://css-tricks.com/myth-busting-css-animations-vs-javascript/

https://www.w3cplus.com/animation/web-animation-api-from-entry-to-the-top.html

https://stackoverflow.com/questions/49628726/what-is-the-purpose-of-angular-animations

虽然说 angular 基于原生来实现,但使用上还是有蛮大区别的。

ng 没有 fill mode, 只能通过 style 来实现最终停留点. (注意: fill mode 会锁死 element 无法在 set style 哦, 通常不会是我们要的,所以我认为 ng 的做法更合理一点)

原生有 play, reverve 等功能,这些是 ng 没有的.

ng 不需要定义初始 style 而且有 * 可以代表当前的 style value, 原生则必须自己去获取所有 value 而且一定要 set start 和 end 2 个,缺一不可.

ng 可以做 group, stagger, query 等等等...原生没有

所以总体来说我还是觉得 ng 的 animation 比较好用。

顺便说一下 css animation 

css aniamtion 的功能弱很多,因为 aniamtion api 本来就是为了弥补 css aniamtion 不足才诞生的.

 

 

refer : 

https://angular.io/guide/animations

https://github.com/angular/angular/blob/master/packages/animations/src/animation_metadata.ts 

https://github.com/angular/angular/commit/f1a9e3c (router)

 

angular 的动画建立在一堆的方法上:  

 

1. trigger
触发器, 用来和 dom 交互 <div [@triggerName]="state" ></div>
trigger 负责定义各种 state 和它们之间变化来变化去 transition

trigger('triggerA', [ 
    state('A', style...),
    state('B', style...), 
    transition('A => B', animate...),
    transition('B => A', animate...)
])

 

2. State
angular 的概念是通过改变状态(state)来触发(trigger)动画(animate)
每个状态都定义了最终的样式

state('A', style...)

 

3. transition
负责定义各种 state 之间错综复杂的转换关系

transition('A => B', animate...)
transition('A <=> B', animate...)
transition('* => *', animate...) * is whatever
transition(':enter', animate...)
transition(':leave', animate...)
transition('* => void', animate...) void表示无, whatever to null 也等于 :leave
transition((fromState, toState) => boolean, animate...) 还可以写方法判断哦 
transition('A => B',[style,animate]) style 也可以放进来哦.
transition('A => B',[animate,animate]) 数组 animate 会按序执行和 transition('A => B', sequence([animate,animate])) 是一样的
transition('A => B',group(animate,animate)) 不想按序执行可以使用 group 

 

到这里可以看出一个基本的流程
[@triggerName]="state" 监听了 state 的变化
一但变化发生触发器就查找匹配的 transition 然后执行 animate. 就这样简单

 

4. Style
就是定义 css 啦

style({ display : 'none' })

 

5. animate
具体的动画定义

animate("5s 10ms cubic-bezier(.17,.67,.88,.1)", style(...)) 

duration= 5second
delay=10ms
easing= cubic-bezier (ease-out 等等 css 有的都可以放)
最后加上 style 就可以动画了咯

animate("5s", keyframes([ 
    style({opacity: 0, offset: 0}),
    style({opacity: 1, offset: 0.3})
])) 

如果你想完全掌握节奏可以使用 keyframes + offset 做定义, offset 0.3 是百分比 

 

6.group
就是把多个 animate 组合起来并发执行.

group(animate,animate)

 

7.keyframes
上面说了


8.sequence
按顺序一个接一个执行, 和 group 刚好打对台, 一个 step by step, 另一个是并发

sequence(animate,animate)

 

 

9.useAnimation

animate是可以封装的. 使用 animation 方法

let fadeAnimation = animation([
    style({ opacity: '{{ start }}' }),
    animate('{{ time }}',
    style({ opacity: '{{ end }}'))
], { params: { time: '1000ms', start: 0, end: 1 }});

 然后在任何想使用 animate 的地方改用 useAnimation

useAnimation(fadeAnimation, {
    params: {
      time: '2s',
     start: 1,
      end: 0
    }
})

 

 

10.query
任何你想使用 animate 的地方都可以使用 query
animate 会施法在当前的 element 上, 而通过 query 你可以施法在 element 的 child 上
query 支持 css 选择器的语法,还有一些 angular 特别的定义语法.

query('css-selector',[animate...])

- Querying for newly inserted/removed elements using `query(":enter")`/`query(":leave")`

这里有个神技 

<div [@listAnimation]="items.length">
    <div *ngFor="let item of items">
        {{ item }}
    </div>
</div>

通过 items.length 配上下面的 transition * => * + query child 就可以实现 items 在插入和移除时的动画了. 

transition('* => *', [  
    query(':leave', [
        stagger(100, [
         animate..
        ])
    ]),
    query(':enter', [        
        stagger(100, [
         animate..
        ])
    ])
])

- Querying all currently animating elements using `query(":animating")`
- Querying elements that contain an animation trigger using `query("@triggerName")`
- Querying all elements that contain an animation triggers using `query("@*")`
- Including the current element into the animation sequence using `query(":self")`

 

11.stagger
stagger 是配合 query 来使用的, 它的作用是当 query select 出很多 element 时,你希望它们不要并发, 而是隔着一个间隔时间.

query('css-selector',[stagger(100,[animate])]) 

比如 select 出 2 个 element, 一个触发动画先,另一个则会等间隔 100ms 后才触发.

 

12.animateChild
animateChild 是一个 manual trigger 概念

<div [@parentAnimation]="exp"> 
    <div [@childAnimation]="exp">
        one
    </div>
</div>

angular 说, 当 parent trigger 触发后,child trigger by default 是不会被触发的 (不过我试了会 /.\)
而我们可以在 parent trigger 中通过 query('@child',[animateChild()]) 来手动触发 child trigger.
这个在做 router animate 时会用到哦.

 

router animation 实现 https://github.com/angular/angular/commit/f1a9e3c 

其实也是依据上面这些方法来做的. 主要用了 parent, child, query, enter, leave, animateChild 这些概念. 

 

posted @ 2017-06-13 23:43  兴杰  阅读(1128)  评论(0编辑  收藏  举报