Angular学习笔记34:Angular动画(2):动画转场1:通配符(*)与void状态

动画转场:通配符与void

预定义状态与通配符匹配
在 Angular 中,转场状态可以通过 state ()函数进行显式定义,或使用预定义的*(通配符)状态和void状态。
在Angular中,转场的动画,可以通过state() 函数进行显示定义,也可以通过Angular预定的 *(通配符) 状态 和void状态。

通配符

“*” 通配符:可以匹配任何一个动画的状态。当不在乎某个HTML元素的起始状态或者结束状态的时候,就可以用到通配符。
例如: 在Angular学习笔记32中,

<div [@stateChange]="isChange?'isYellow':'isGreen'">
  <p>
    Angular学习笔记
  </p>
</div>

当不在乎

这个元素的结束状态或者开始状态的时候,就可以使用 “*” 这个通配符了。

使用多个转场状态的通配符(*)

有时候在做动画的时候,会遇到,对于某一个元素,会有不止两个的状态,例如如下:

animations: [
  // 定义动画的触发器放在 animations 元数据属性中*
trigger('stateChange', [
    state('isYellow', style(
      {
        height: '200px',
        width: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      }
    )),
    state('isGreen', style(
      {
        height: '100px',
        width: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      }
    )),
    state('isRed', style(
      {
        height: '100px',
        width: '100px',
        opacity: 0.5,
        backgroundColor: 'red'
      }
    )),
    transition('isYellow => isGreen', animate('1s')),
    transition('isGreen => isYellow', animate('2s')),
  ])
],

假设需要 isYellow 的状态和 isGreen 的状态相互转换的时候,都需要1s时间,正常情况如下写:

transition('isYellow => isGreen', animate('1s')),
transition('isGreen => isYellow', animate('1s')),

此时就可以使用双向箭头语法(<=>),从而指定任意方向的转场,故上面的代码可以简化为:

transition('isYellow <=> isGreen', animate('1s')),

在这里定义了有三个状态分别是:isYellow,isGreen,isRed,这三种状态。
这个时候,在状态于状态之间转换的时间是设定这里,在这个元素向isRed这个状态的时候,都需要0.5s转场时间,这个时候,就不用去写如下:

transition('isYellow => isRed', animate('0.5s')),
transition('isGreen => isRed', animate('0.5s')),

这个时候就可以使用通配符了,故上面的代码就可以简化为:

transition('* => isRed', animate('0.5s')),

在这个时候,我们在设置这三种状态在任意状态转化的时候,都要经历5s,从而验证一下动画匹配的优先级。

transition('* => *', animate('5s')),

从而animations数组具体如下:

animations: [
  // 定义动画的触发器放在 animations 元数据属性中*
trigger('stateChange', [
    state('isYellow', style(
      {
        height: '200px',
        width: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      }
    )),
    state('isGreen', style(
      {
        height: '100px',
        width: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      }
    )),
    state('isRed', style(
      {
        height: '150px',
        width: '150px',
        opacity: 0.5,
        backgroundColor: 'red'
      }
    )),
    transition('isYellow <=> isGreen', animate('1s')),
    transition('* => isRed', animate('0.5s')),
    transition('* => *', animate('5s')),
  ])
],

修改模版文件为如下:

<div [@stateChange]="isChange">
  <p>
    Angular学习笔记
  </p>
</div>

<button nz-button (click)="handleChange('isRed')">改变为红色</button>
<button nz-button (click)="handleChange('isYellow')">改变为黄色</button>
<button nz-button (click)="handleChange('isGreen')">改变为绿色</button>

修改类文件如下:

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

@Component({
  selector: 'app-animation-demo',
  templateUrl: './animation-demo.component.html',
  styleUrls: ['./animation-demo.component.less'],
  animations: [
    // 定义动画的触发器放在 animations 元数据属性中*
trigger('stateChange', [
      state('isYellow', style(
        {
          height: '200px',
          width: '200px',
          opacity: 1,
          backgroundColor: 'yellow'
        }
      )),
      state('isGreen', style(
        {
          height: '100px',
          width: '100px',
          opacity: 0.5,
          backgroundColor: 'green'
        }
      )),
      state('isRed', style(
        {
          height: '150px',
          width: '150px',
          opacity: 0.5,
          backgroundColor: 'red'
        }
      )),
      transition('isYellow <=> isGreen', animate('1s')),
      transition('* => isRed', animate('0.5s')),
      transition('* => *', animate('5s')),
    ])
  ],
})
export class AnimationDemoComponent  implements OnInit{
  public isChange = false;

  constructor() {
  }

  ngOnInit() {
  }

  public handleChange(state): void {
    this.isChange = state;
  }

}

在这里插入图片描述

通过上面的动画可以看到,当任意状态向红色变更的时候,转场:

transition('* => *', animate('5s')),

被覆盖,使用了转场:

transition('* => isRed', animate('0.5s')),

从而可以看到,* => *优先级最低,而后才是 * => isRed;
将三个转场调顺如下:

animations: [
  // 定义动画的触发器放在 animations 元数据属性中*
trigger('stateChange', [
    state('isYellow', style(
      {
        height: '200px',
        width: '200px',
        opacity: 1,
        backgroundColor: 'yellow'
      }
    )),
    state('isGreen', style(
      {
        height: '100px',
        width: '100px',
        opacity: 0.5,
        backgroundColor: 'green'
      }
    )),
    state('isRed', style(
      {
        height: '150px',
        width: '150px',
        opacity: 0.5,
        backgroundColor: 'red'
      }
    )),
    transition('* => *', animate('5s')),
    transition('isYellow <=> isGreen', animate('1s')),
    transition('* => isRed', animate('0.5s')),
  ])
],

然后运行保存,动画如下:

demo1

从而可以验证,如果要确保特殊的转场要被使用,就要保证,所有特殊的转场动作都要放在transition(’* => *’, animate(‘5s’)), 之前。

  • 在样式中使用通配符(*)
transition(* => isRed’, animate(0.5s’, style({opacity:*}))),

在这个时候,动画就会使用当前的状态的配置值,从而进行动画。

特殊状态:void状态

具体:Void状态来为进入或离开页面的元素配置转场,也可以理解为:将元素从DOM中插入或者删除。

组合使用通配符(*)和void状态你可以在转场中组合使用通配符和void状态,以触发那些进入和离开页面的动画:

  • 当元素离开视图时(这个元素从DOM删除的时候),就会触发* => void转场,而不管它离开前处于什么状态。

  • 当元素进入视图时(这个元素被插入到DOM的时候),就会触发void => *转场,而不管它进入时处于什么状态。

注意:通配符状态(*)会匹配任何状态(包括void)

现在来做一个将一个元素插入DOM的时候从左飞入,删除DOM的时候,从右边飞出的动画

修改模版文件为如下:

<div [@stateChange]="isChange">
  <p>
    Angular学习笔记
  </p>
</div>

<button nz-button (click)="handleChange('isRed')">改变为红色</button>
<button nz-button (click)="handleChange('isYellow')">改变为黄色</button>
<button nz-button (click)="handleChange('isGreen')">改变为绿色</button>


<nz-divider [nzText]="'飞入飞出动画'"></nz-divider>
<nz-row>
  <nz-form-control [nzSpan]="4" nzOffset=*"10">
    <div>
      飞入飞出动画~
    </div>
  </nz-form-control>
</nz-row>

添加元素插入DOM 的状态:

state('flyIn', style({
  transform: 'translateX(0)',
  color: 'blue',
})),

添加进入视图的转场(插入DOM):

transition('void => *', [
  style({
    transform: 'translateX(-100%)',
    color: 'yellow'
  }),
  animate('2s')
]),

添加离开视图的转场(从DOM中删除):

transition('* => void', [
  animate('2s', style({
    transform: 'translateX(100%)',
    color: 'red'
  })),
])

将上述添加到一个触发器中:

trigger('fly', [
  state('flyIn', style({
    transform: 'translateX(0)',
    color: 'blue',
  })),
  transition('void => *', [
    style({
      transform: 'translateX(-100%)',
      color: 'yellow'
    }),
    animate('2s')
  ]),
  transition('* => void', [
    animate('2s', style({
      transform: 'translateX(100%)',
      color: 'red'
    })),
  ])
])

在类文件中增加一个属性来控制元素的插入和删除

export class AnimationDemoComponent  implements OnInit {
  public isChange = false;
  public isInOut =  false;

  constructor() {
  }

  ngOnInit() {
  }

  public handleChange(state):  void{
    this.isChange = state;
  }

  public handleInOut() {
    this.isInOut = !this.isInOut;
  }

}

在Angular中,可以使用*ngIf指令来控制将元素从DOM删除或者插入。故修改模版文件:

<div [@stateChange]="isChange">
  <p>
    Angular学习笔记
  </p>
</div>

<button nz-button (click)="handleChange('isRed')">改变为红色</button>
<button nz-button (click)="handleChange('isYellow')">改变为黄色</button>
<button nz-button (click)="handleChange('isGreen')">改变为绿色</button>


<nz-divider [nzText]="'飞入飞出动画'"></nz-divider>
<nz-row>
  <button nz-button (click)="handleInOut()">按钮</button>
</nz-row>
<nz-row>

  <nz-form-control nzSpan="10" nzOffset="7">
    <div style="text-align: center;background: red" *ngIf="isInOut"  [@fly]="isInOut?'flyIn':'void'">
      飞入飞出动画~
    </div>
  </nz-form-control>
</nz-row>

保存运行后,可以看到:
fly

两个重要的状态别名(:enter 和 :leave)

在Angular中:enter 和 :leave 分别是 void => * 和 * => void 的别名。
所以之前的代码就也可以写成:

transition(':enter', [
        style({
          transform: 'translateX(-100%)',
          color: 'yellow'
        }),
        animate('2s')
      ]),
      transition(':leave', [
        animate('2s', style({
          transform: 'translateX(100%)',
          color: 'red'
        })),
      ])

这样也可以达到同样的效果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值