angular的动画如何使用?

172 阅读3分钟

功能:

  • 给元素添加动态效果

步骤

  • 要想实现动画效果,得分三步

    1. 定义不同状态的展示效果
    2. 定义状态切换时的动画(比如持续时间)
    3. 定义逻辑切换动画状态

背景

下面以此例—(鼠标移入时就展示完全,移出时就移动页面底下隐藏起来的效果)来看动画是如何使用的

移入

移出

1.定义状态

  • 通过state() 定义状态。

    • 参数

      • state(status,style)

        • status:str类型,一个状态的表示
        • style:当前状态下的具体样式
    • 案例

      • 注意,在定义状态的函数中,样式的属性必须是小驼峰格式的。
@Component({
  ...,
  animations: [
  // showHide为动画的名字,用来后续挂载到组件元素上
  trigger('showHide', 
    [
      state('show', style({backgroundColor:'black',bottom: 0})),
      state('hide', style({backgroundColor:'red',bottom: -71})),
      
    ]
  )]
})

2.定义转场动画:transition()

  • 使用格式:

    参数1:表达式:定义两个状态之间的切换方向

    参数2:第二个参数接受一个或一系列 animate 函数。

image.png

  • 例子
@Component({
  ...,
  animations: [trigger('showHide', [
    state('show', style({backgroundColor:'black',bottom: 0})),
    state('hide', style({backgroundColor:'red',bottom: -71})),
    transition('show=>hide', [animate('0.3s')]),
    transition('hide=>show', [animate('0.1s')]),
  ])]
})

3. 使用动画

  1. 通过在html标签上写[@animationName] =val的形式标明哪个元素要用你前面定义的动画

    • trigger() 函数的第一个参数定义的是动画名称。定义好后,在HTML模板中,给动画名称加上个@前缀就行
<div
     [@showHide]="showPlayer"
     (mouseenter)="togglePlayer('show')"
     (mouseleave)="togglePlayer('hide')"
     (@showHide.start)="animating=true"
     (@showHide.done)="animating=false"
>
  1. 如何让组件知道当前应该展示哪个状态的样式?

    1. 定义一个变量用来存储当前要展示哪个样式

    2. 定义函数改变当前要展示的状态

    • 这里就需要给之前的动画名称传递一个当前要展示的状态值。通过这样来实现不同状态样式的展示。
 <div
     [@showHide]="showPlayer"
     (mouseenter)="togglePlayer('show')" // 鼠标移入移除时,showPlayer的值为括号内的内容,也即切换状态
     (mouseleave)="togglePlayer('hide')"
     (@showHide.start)="animating=true"
     (@showHide.done)="animating=false"
>

// showPlayer就用来存show或hide
  1. 避免因操作过快而导致样式切换鬼畜

    • 背景

      • 比如上面的效果就是在你鼠标移入移出的时候改变bottom的值,来确保其展示在不同的位置,而一旦你鼠标移动速度过快,它还没展示完全呢,你就移出去了,那就会导致这个元素展示忽高忽低地鬼畜效果。
    • 解决措施

      • 用一个变量来存储当前是否正处于上一个状态切换的动画过程,若是,那即使改变状态的那个函数被触发了也不走到真正改变值的那句代码
    • 具体代码

  • html

     <!--(@showHide.start)和 (@showHide.done) 分别表示动画的开始和结束-->
    <div class="m-player" appClickOutSide
         [@showHide]="showPlayer"
         (onClickOutside)="onClickOutside()"
         [bindFlag]="bindFlag"
         (mouseenter)="togglePlayer('show')"
         (mouseleave)="togglePlayer('hide')"
    
         (@showHide.start)="animating=true"
         (@showHide.done)="animating=false"
    >
    ...
    </div>
    
  • js

    @Component({
      ....,
      animations: [trigger('showHide', [
        state('show', style({backgroundColor:'black',bottom: 0})),
        state('hide', style({backgroundColor:'red',bottom: -71})),
        transition('show=>hide', [animate('0.3s')]),
        transition('hide=>show', [animate('0.1s')]),
      ])]
    })
    
    animating = false; // 是否正在动画中
    
    togglePlayer(type: string) {
        if (!this.animating) { 
          this.showPlayer = type;
        }
      }
    

一些概念

  • 转场状态

    • void:表元素创建好但还没插入到DOM中,或从DOM中删除。

      • 当元素离开视图时,就会触发 * => void 转场,而不管它离开前处于什么状态。

        A transition of * => void applies when the element leaves a view, regardless of what state it was in before it left.

      • 当元素进入视图时,就会触发 void => * 转场,而不管它进入时处于什么状态。

    • *:表任何一个动画状态

    • custom : 自定义状态

    • 当在_任意_两个状态之间切换时,* => * 转场都会生效。

      • 此转场使用场景:

        • 因为转场会按照其定义的顺序进行匹配。所以* => * 可以作为前面的转场都没匹配成功时的备用品。