Angular Animation

       Angular Animation简单来说 就是状态和状态之间的转场效果。每一种状态对应一种样式(style)。Angular Animation指导从一种状态的样式过渡到另一种状态的样式效果过程。

Angular Animation和咱们Android里面的属性动画类似。

       如果想在我们的应用中使用动画,有一个前提条件,得先引入BrowserAnimationsModule模块。建议在app module里面引入。

       开始部分,我们先贴出文章里面涉及到的所有例子的下载的地址:https://github.com/tuacy/AngularAnimation

       例子都是非常简单的例子,咱也是个初学者。高深的例子咱也写不出来。

一、Angular Animation里面各个函数解释

       Angular Animation动画使用起来不难,在加上咱之前有Android动画的经验。Angular Animation看起来就更加的简单了。

1.1. trigger触发器

        trigger触发器,trigger将根据提供的triggerName值创建一个动画触发器。在模板中使用[@triggerName]语法来把它附加到一个或多个元素上去。可以简单的理解为这个时候就把元素和触发器对应的动画绑定起来了。

       比如如下的代码我们就定义了一个名字为flyInOut的一个触发器。

import {Component, OnInit} from '@angular/core';
import {animate, keyframes, state, style, transition, trigger} from '@angular/animations';

@Component({
    selector: 'app-keyframes-animation',
    templateUrl: './keyframes-animation.component.html',
    styleUrls: ['./keyframes-animation.component.css'],
    animations: [
        trigger('flyInOut', [
            state('in', style({transform: 'translateX(0)'})),
            // keyframes多阶段动画(任何状态切换的时候都使用该动画)
            transition('* => *', [
                animate(1000, keyframes([
                    style({opacity: 0, transform: 'translateX(-100%)', offset: 0}),
                    // 多往右边移除一点
                    style({opacity: 1, transform: 'translateX(50%)', offset: 0.5}),
                    style({opacity: 1, transform: 'translateX(0)', offset: 1.0})
                ]))
            ])
        ])
    ]
})
export class KeyframesAnimationComponent implements OnInit {

    constructor() {
    }

    ngOnInit() {
    }

}

       上面的代码只是定义了一个触发器,但是还没有把触发器和页面上的元素绑定起来(在模板中使用[@triggerName]来绑定),比如如下的代码我们就把div绑定到了这个触发器上。


keyframes关键帧多阶段动画


1.2. state状态

       state状态,通过这个state函数来定义每个状态最终的样式(动画开始时候的样子和动画结束之后的样子);想要动画动起来需要通过改变状态(state)来触发(trigger)动画(animate)。

上面咱们贴了trigger触发器时候的代码实例,在trigger函数里面有state函数,定义了一个 in的状态对应的样式为transform: 'translateX(0)'。

1.3. transition转换

       transition负责定义各种 state之间的转换关系,并且定义state转换的时候使用什么的样的动画来完成。

       这里我们着重要讲下状态装换在Angular Animation中是怎么定义的状态之间装换的。

trigger('animationState', [
            // stateA 状态最终样式
            state('stateA', style({
                backgroundColor: '#67ee38',
                transform: 'scale(1)'
            })),
            // stateB 状态最终样式
            state('stateB', style({
                backgroundColor: '#4a302c',
                transform: 'scale(1.1)'
            })),
            // stateA 到 stateB 状态动画
            transition('stateA => stateB', animate('500ms ease-in')),
            // stateB 到 stateA 状态动画
            transition('stateB => stateA', animate('500ms ease-out'))
        ]),

       上面的代码trigger里面有两个transition。分别定义了'stateA => stateB'和'stateB => stateA'的状态变化。Angular Animation里面两个状态之间的装换就是通过 '状态 => 状态' 这样的表达式来定义的。在Angular Animation里面有两种特殊的状态; ×、void状态。其中×状态匹配任何状态,void状态表示元素没有被附加到视图时候的状态。

       讲到状态,那咱们还得提下元素的入场和出场动画的添加了。比如下面的实例。我们定义了入场和出场的动画。

    animations: [
        trigger('flyInOut', [
            state('in', style({opacity: 1, transform: 'translateX(0) scale(1)'})),
            // 进场动画
            transition('void => *', [
                style({opacity: 0, transform: 'translateX(-100%) scale(0)'}),
                animate(500)
            ]),
            // 出场动画
            transition('* => void', [
                animate(500, style({opacity: 0, transform: 'translateX(100%) scale(0)'}))
            ])
        ])
    ]

应该比较好理解吧,void => * 表示入场。* => void 表示出场。当然入场你也可以用:enter代替,出场可以用:leave代替。

animation_enter.gif

1.4. style样式

       Angular Animation动画的过程就是在改变元素的CSS样式或者CSS3 transform 属性。style函数可以出现在state函数,transition函数,animate函数中。

       假设有这样的需求,动画结束但是我们不想保留动画结束点的那个状态。实现过程查看如下代码。

 // 动画结束不保留状态
        trigger('animationStateNoSave', [
            transition('stateA => stateB', [
                style({
                    backgroundColor: '#4a302c',
                    transform: 'scale(1.1)'
                }),
                animate('1000ms ease-in', style({
                    backgroundColor: '#67ee38',
                    transform: 'scale(1)'
                }))
            ]),
            transition('stateB => stateA', [
                style({
                    backgroundColor: '#67ee38',
                    transform: 'scale(1)'
                }),
                animate('1000ms ease-in', style({
                    backgroundColor: '#4a302c',
                    transform: 'scale(1.1)'
                }))
            ])
        ])

注意这里我们没有通过state函数来指定状态对应的style。

       Angular Animation支持的CSS样式如下:

css属性的名字 animation style 对应名字 解释
background-color backgroundColor 设置元素的背景颜色
background-position backgroundPosition 设置背景图像的起始位置
border-bottom-color borderBottomColor 设置下边框的颜色
border-bottom-width borderBottomWidth 设置下边框的宽度
border-left-color borderLeftColor 属性设置元素的左边框的颜色
border-left-width borderLeftWidth 属性设置元素的左边框的宽度
border-right-color borderRightColor 属性设置元素的右边框的颜色
border-right-width borderRightWidth 属性设置元素的右边框的宽度
border-spacing borderSpacing 设置相邻单元格的边框间的距离
border-top-color borderTopColor 属性设置元素的上边框的颜色
border-top-width borderTopWidth 属性设置元素的上边框的宽度
bottom bottom 定元素的底部边缘
clip clip 剪裁绝对定位元素
color color 规定文本的颜色
font-size fontSize 设置字体的尺寸
font-weight fontWeight 设置文本的粗细
height height 设置元素的高度
left left 设置元素的左边缘
letter-spacing letterSpacing 设置字符间的空白(字符间距)
line-height lineHeight 设置行间的距离(行高)
margin-bottom marginBottom 设置元素的下外边距
margin-left marginLeft 设置元素的左外边距
margin-right marginRight 设置元素的右外边距
margin-top marginTop 设置元素的上外边距
max-height maxHeight 设置元素的最大高度
max-width maxWidth 设置元素的最大宽度
min-height minWidth 设置元素的最小高度
min-width minWidth 设置元素的最小宽度
opacity opacity 设置元素的不透明级别
outline-color outlineColor 设置元素整个轮廓的颜色
outline-width outlineWidth 设置元素整个轮廓的宽度
padding-bottom paddingBottom 设置元素的下内边距
padding-left paddingLeft 设置元素的左内边距
padding-right paddingRight 设置元素的右内边距
padding-top paddingTop 设置元素的上内边距
right right 规定元素的右边缘
text-indent textIndent 首行文本的缩进
text-shadow textShadow 向文本设置阴影
top top 规定元素的顶部边缘
visibility visibility 规定元素是否可见
width width 元素的宽度
word-spacing wordSpacing 设置单词间的空白
z-index zIndex 设置元素的堆叠顺序

       Angular Animation支持的CSS3
transform 属性如下:

transform 属性 描述
matrix(n,n,n,n,n,n) 2D 转换,使用六个值的矩阵
matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n) 3D 转换,使用 16 个值的 4x4 矩
translate(x,y) 2D 转换
translate3d(x,y,z) 3D 转换。
translateX(x) 转换,只是用X轴
translateY(y) 转换,只是用 Y 轴的值
translateZ(z) 3D 转换,只是用 Z 轴的值。
scale(x,y) 缩放转换
scale3d(x,y,z) 3D 缩放转换。
scaleX(x) 通过设置 X 轴的值来定义缩放转换
scaleY(y) 通过设置 Y 轴的值来定义缩放转换
scaleZ(z) 通过设置 Z 轴的值来定义 3D 缩放转换。
rotate(angle) 2D 旋转,在参数中规定角度
rotate3d(x,y,z,angle) 3D 旋转。
rotateX(angle) 沿着 X 轴的 3D 旋转
rotateY(angle) 沿着 Y 轴的 3D 旋转
rotateZ(angle) 沿着 Z 轴的 3D 旋转
skew(x-angle,y-angle) 沿着 X 和 Y 轴的 2D 倾斜转换
skewX(angle) 沿着 X 轴的 2D 倾斜转换
skewY(angle) 沿着 Y 轴的 2D 倾斜转换
perspective(n) 3D 转换元素定义透视视图

1.5. animate动画

       animate表示具体的动画定义
。定义动画的持续时间,动画延时多长时间执行,动画的缓动函数(https://easings.net/zh-cn)。

1.6. group组

       group是一个动画特定的函数,指定一个并行运行的动画步骤列表。分组动画是当一系列样式必须在不同的开始/结束时间进行动画/关闭时很有用。同时执行多个动画。(多个动画组合在一起同时触发)。比如如下效果图,同时有颜色变化动画和翻转动画执行。

animation_并行动画.gif

1.7. keyframes关键帧

       keyframes描述每个样式条目是如何应用的,以及在什么点动画弧(很像CSS关键帧动画)。相当于把动画分段了。比如如下动画我们通过keyframes实现了动画多往左边移动了一段距离在回到最终位置(当然了你也可以通过缓动函数来实现)。

animation_keyframes.gif

1.8. sequence顺序

       sequence指定逐个运行的动画步骤列表,这个也就是和group特性正好相反,一个同时进行,一个按先后顺序一个一个的进行。

比如下面的例子,进场动画我们就定义了几个动画顺序执行

import {Component, OnInit} from '@angular/core';
import {animate, sequence, state, style, transition, trigger} from '@angular/animations';

@Component({
    selector: 'app-sequence-animation',
    templateUrl: './sequence-animation.component.html',
    styleUrls: ['./sequence-animation.component.css'],
    animations: [
        trigger('flyInOut', [
            state('in', style({transform: 'rotateX(0) translateX(0)', opacity: 1})),
            // 多个动画同时执行
            transition('void => *', sequence([
                style({
                    opacity: 0,
                }),
                animate('1s ease-in-out', style({
                        opacity: 1,
                    }
                )),
                animate('1s ease-in-out', style({
                        transform: 'rotateX(90deg)',
                    }
                )),
                animate('2s ease', style({
                    transform: 'rotateY(90deg)',
                })),
            ]))
        ])
    ]
})
export class SequenceAnimationComponent implements OnInit {

    constructor() {
    }

    ngOnInit() {
    }

}

animation_顺序动画.gif

1.10. query

       query用于在当前元素中查找(query)一个或多个内部元素在序列中进行动画。把动画作用在子元素上。

import {Component, OnInit} from '@angular/core';
import {animate, query, style, transition, trigger} from '@angular/animations';

@Component({
    selector: 'app-query-animation',
    templateUrl: './query-animation.component.html',
    styleUrls: ['./query-animation.component.css'],
    animations: [
        trigger('queryAnimation', [
            // 入场的时候对子元素采用动画
            transition('* => goAnimate', [
                // hide the inner elements
                query('h1', style({
                    opacity: 0
                })),
                query('.content', style({
                    opacity: 0
                })),
                // 动画作用于内容元素
                query('h1', animate(1000, style({
                    opacity: 1
                }))),
                query('.content', animate(1000, style({
                    opacity: 1
                })))
            ])
        ])
    ]
})
export class QueryAnimationComponent {

}

animation_子元素.gif

1.11. stagger

       stagger需要在query里面使用,stagger的作用在于每个动画发出之后隔多长时间在发下一个动画。比如咱们有这样的需求,ul里面有好多个li。想要一个这样的效果。li的动画一个挨着一个执行。代码如下

        trigger('listAnimation', [
            transition('* => *', [ // each time the binding value changes
                query(':enter', [
                    // 所有子元素入场动画
                    style({opacity: 0}),
                    stagger('0.5s', [
                        animate('0.5s', style({opacity: 1}))
                    ])
                ])
            ])
        ])]

1.12. animateChild

       在angular中,因为每次动画被触发,父动画将始终获得优先权,任何子动画都将被阻止,为了子动画也有动画效果,父动画必须查询每一个包含子动画的元素并用animateChild来运行子动画。animateChild需要和query一起使用。

trigger('parentAnimation', [
            transition('false => true', [
                // 查找parentAnimation对应element里面的header标签执行动画
                query('header', [
                    style({opacity: 0}),
                    animate(500, style({opacity: 1}))
                ]),
                query('@childAnimation', [
                    animateChild()
                ])
            ])
        ]),
        trigger('childAnimation', [
            transition('false => true', [
                style({opacity: 0}),
                animate(500, style({opacity: 1}))
            ])
        ])

1.13. 动画回调

       动画开始的时候有个回调函数,动画结束的时候也有个回调函数。

1.9. animation的封装

       借助useAnimation函数我们可以对动画做一个简单的封装。比如如下的代码我们把封装了两个动画,放在animation.ts文件里面。

import {animate, animation, style, transition, trigger, useAnimation} from '@angular/animations';

// 封装动画1
const inAnimation = animation([
    style({
        opacity: '{{ start }}',
        transform: 'translateX(-100%)'
    }),
    animate('{{ time }}',
        style({
            opacity: '{{ end }}',
            transform: 'translateX(0)'
        }))
], {params: {time: '1000ms', start: 0, end: 1}});

// 封装动画2
const outAnimation = animation([
    style({
        opacity: '{{ start }}',
        transform: 'translateX(0)'
    }),
    animate('{{ time }}',
        style({
            opacity: '{{ end }}',
            transform: 'translateX(-100%)'
        }))
], {params: {time: '1000ms', start: 0, end: 1}});


// 如下面我定一个动效用到上面封装的动画
export const routerEnterLeave = trigger('fadel', [
    // 入场
    transition(':enter', [
        useAnimation(inAnimation, {
            params: {
                time: '2s',
                start: 0,
                end: 1
            }
        })
    ]),
    // 出场
    transition(':leave', [
        useAnimation(outAnimation, {
            params: {
                time: '2s',
                start: 1,
                end: 0
            }
        })
    ])
]);


       关于Angular Animation咱们就撤这么多,文章中涉及到的所有例子下载地址https://github.com/tuacy/AngularAnimation。希望能帮到大家。最后还是想强调下最好的文档是官方文档https://v6.angular.live/guide/animations。

你可能感兴趣的:(Angular Animation)