zoukankan      html  css  js  c++  java
  • angular2的动画

    谈起angular2(现在已经angular4)了,个人觉得angular2的官方文档不太适合初学者,所以每一块弄懂都不那么容易。

    为了弄懂angular的动画自己也是花了一番功夫,不客观的说,angular的动画写起来是比较复杂的,但又必须掌握。

    下面是我结合官方文档以及王芃老师写的资料,自己通过实践写出来的一篇博客,希望可以帮到有需求的小伙伴,当然,如果文章有地方写的错误,欢迎指正。

    好了,废话不多说,开始正文吧。

    1:angular动画的使用需要先引入一些与动画有关的函数。

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

    组件里引用:(:暂时先在组件里写动画相关的代码,文末会把它单独抽离出来

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

    :有些小伙伴的项目开始的时候可能没有动画相应的资源包,请暂时允许我这么说。此时你就需要在项目依赖包里先加入这个资源。

    如何加入呢?定位到你的项目上,命令行输入:

    npm install @angular/animations --save

    当你检查到你的package.json里出现:

    此时说明动画资源已经被成功下载了。ok,现在我们开始动画吧:

    ********:开始第一个动画(交通信号灯..):

    1:请首先在你的组件.ts代码里的@Component装饰器里添加如下代码:

    animations: [
        trigger('signal', [
          state('go', style({
            'background-color': 'green'
          }))
        ])
      ]

    模板(html)里添加:

    <div class="traffic-light" [@signal]="'go'"></div>

    css里样式:

    .traffic-light{   100px;  height: 100px;  background-color: black;  }

    本来div定义的样式背景色是黑色,但是div在页面中却呈现的是绿色,见图:

    现在问题来了,绿色怎么来的呢 ? 见图:

    因为div元素此时处于动画里的go状态。所以div具有go状态里被描述的动画样式。

    如果你不懂为什么要这样定义动画,暂时你只需要知道这样写就行了。

    2:让我们加入两个按钮,此时两个按钮要做的是:让div元素切换不同的背景色

    此时可能有的小伙伴会觉得我直接用js写不就好了吗?(下面用原生js仅为提供意思,

    btn1.onclick = function(){
        div.style.background = 'xxx';        
    }
    
    btn2.onclick = function(){
        div.style.background = 'xxx';        
    }

    请先务着急,不妨先看看利用动画是如何制作呢。见模板:图

    见ts:图

    这个切换div不同背景颜色样式上,实质的就是通过按钮事件切换div的两种动画状态

    3:让我们来点复杂一点的:(:   见图:

    这个具备时间过渡的动画的怎么来的呢?我们先见代码:

    在ts代码里我只加了三句代码,其中两句是描述状态中高度的变化,相信小伙伴们都懂,着重看看这个  ‘* => *’

    问题来了,这个 * = >* 是个什么东西呢?

    答:它是一个状态迁移表达式,* 表示任意状态,所以这个表达式告诉我们,只要有状态的变化就会激发后面的动画效果,使得元素做500毫秒的动画。

    也可以粗暴的这么讲:*号匹配任意状态,由 transition 关键字定义 何种状态过渡到何种状态。 只要状态发生变化,就会执行 transition 里的anmate函数

    它类似于:

    但不同的是,当第一次点击的是stop的按钮时,这么div是没有出现时间过渡的。那是因为go状态在stop之前定义,

    先点击stop时,不走transition这条定义。当点了go按钮触发go状态时,stop的过渡才会生效

    4:然后介绍下一个特殊的状态void, 何为void状态呢,我们先添加一段代码,见下图:

    然后我们再看一下效果:

     我们会看见当页面刷新的时候,div元素从页面上方进入页面。这个动画如何产生的呢?再重复看这两段代码:

     

    会发现,在class里我并没有给signal成员变量赋初始值,这就意味着一开始trigger的状态就是void

    void状态就是描述没有状态值时的状态,我们往往在实现进场或离场动画时需要这个void状态。

    当然,void状态也是一种任意状态。所以:

    transition('*=> *', animate(500))   
    
    //在这里等同于
    
    transition('void => *', animate(500))   

     注:void状态的动画只是拿来“过渡”用的,它描述的样式不是最终的样式,而是过渡过程中产生的样式,在规定的时间内完成后它是被“清除掉的”。

    所以,这个动画会在我规定的500毫秒里完成一个按Y轴做的-100%的位移。

    5:当你看到,transition里的animate时会不会觉得似曾相识呢?没错,它和css3里的animation几乎是一样的

    所以当然我们可以使用延迟,缓动函数,关键帧等来定义我们的动画:

    我们来见一个详细的例子。

    模板:

    <div class="traffic-light" [@signal]="signal"></div>
    
    <button (click)="go()">go</button>
    <button (click)="stop()">stop</button>

    ts:

    import { Component } from '@angular/core';
    import {trigger, state, style, animate, transition,keyframes} from '@angular/animations';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
      animations: [
        trigger('signal', [
          state('void', style({
            'transform':'translateX(-100%)'
          })),
          state('go', style({
            'background-color': 'green',
            'height':'100px'
          })),
          state('stop', style({
            'background-color':'red',
            'height':'50px'
          })),
          transition('void => *', animate(5000, keyframes([
            style({'transform': 'scale(0)'}),
            style({'transform': 'scale(0.1)'}),
            style({'transform': 'scale(0.3)'}),
            style({'transform': 'scale(0.6)'}),
            style({'transform': 'scale(0.8)'}),
            style({'transform': 'scale(1)'})
          ]))),
          transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))
        ])
      ]
    })
    export class AppComponent {
      signal:string;
    
      stop(){
        this.signal = 'stop';
      }
    
      go(){
        this.signal = 'go';
      }
    }

    我们来见一下具体表现:

    这个动画是怎么产生的呢?

    先见

    在这个transition定义里,动画共持续了五秒,对应的是每一个style,共分为:0s,1s,2s,3s,4s和5s

     也就是当浏览器刷新时,入场动画 void=>*的过程。

    **我们有看见当我点击go or stop按钮时,按钮等待了一点时间才执行动画,是怎么回事呢?我们看这个transition的定义:

    transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))

    这个状态定义表示任意状态到任意状态的过程,也就是我们点击按钮div当前的状态go or stop的状态,表现为动画1秒延迟后div以0.5秒的时间完成这个动画。

    可能有的人会问最后那个div元素有反弹的效果是因为什么呢?这篇文章就不做解释了,如果有兴趣你可以搜一下贝塞尔曲线

    至此,angular2的动画就介绍完毕了。嗷嗷,对了,这种在组件里写动画的方式是不够优雅的,我们可以把这个动画单独提取出来,如何提取呢?

    1:新创建一个动画的ts文件,如animate.ts:

    import {trigger, state, style, animate, transition,keyframes} from '@angular/animations';
    
    export const SingalAnimate = trigger('signal', [
        state('void', style({
            'transform':'translateX(-100%)'
        })),
        state('go', style({
            'background-color': 'green',
            'height':'100px'
        })),
        state('stop', style({
            'background-color':'red',
            'height':'50px'
        })),
        transition('void => *', animate(5000, keyframes([
            style({'transform': 'scale(0)'}),
            style({'transform': 'scale(0.1)'}),
            style({'transform': 'scale(0.3)'}),
            style({'transform': 'scale(0.6)'}),
            style({'transform': 'scale(0.8)'}),
            style({'transform': 'scale(1)'})
        ]))),
        transition('* => *', animate('.5s 1s cubic-bezier(0.2, 0.8, 0.3, 1.8)'))
    ]);

    2:而后,在组件ts里引入:

    import { SingalAnimate } from './animate';

    3:最后,在元数据animation 里添加:

    animations: [ SingalAnimate ]

    npm start, 看看效果吧~

    至此,angular2动画也就结束了。

  • 相关阅读:
    为什么java的接口的方法是public abstract修饰?为什么属性是public static final 修饰?
    java方法的重载
    java的自增和自减
    html和jsp页面中把文本框禁用,只能读不能写的方法
    JavaScript的数据类型有哪些?
    thinkPHP 框架 delete方法无法删除数据 【已解决】
    Linux shell 数组
    redis cpu占用过高100%,清理病毒事件
    Linux 批量杀掉进程
    记一次宝塔Linux面板磁盘占满,删除文件后空间没有减少的问题
  • 原文地址:https://www.cnblogs.com/cyfm/p/6913929.html
Copyright © 2011-2022 走看看