Angular动画教程(一)有哪些内容?

2026-05-05 22:562阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1931个文字,预计阅读时间需要8分钟。

Angular动画教程(一)有哪些内容?

访问以下链接,查看Angular动画探索器的示例:

[https://williamjuan027.github.io/angular-animations-explorer/home](https://williamjuan027.github.io/angular-animations-explorer/home)

使用`BrowserAnimationsModule`模块,以下是一个简单的组件示例,包含动画:

typescript@Component({ selector: 'app-animation-example', templateUrl: './animation-example.component.', styleUrls: ['./animation-example.component.css'], animations: [ trigger('enabledStateChange', [ state('default', style({ opacity: 1 })), state('disabled', style({ opacity: 0.5 })), transition('default=> disabled', animate('300ms')), transition('disabled=> default', animate('300ms')) ]) ]})export class AnimationExampleComponent { // 组件逻辑}

williamjuan027.github.io/angular-animations-explorer/home

注入模块

BrowserAnimationsModule 来个小案例

@Component({ ... animations: [ trigger('enabledStateChange', [ state('default', style({opacity: 1})), state('disabled', style({opacity: .5, background: '#000'})), transition('* => *', animate('1500ms ease-out')) ]), ] }) stateOfElement = 'default'; toggleMethod() { this.stateOfElement = this.stateOfElement === 'default' ? 'disabled' : "default" }

<div [@enabledStateChange]="stateOfElement"></div> <button (click)="toggleMethod()">Click</button> trigger

trigger(name: string, definitions: AnimationMetadata[]): AnimationTriggerMetadata 参数 name string 一个标识字符串。 definitions AnimationMetadata[] 一个动画定义对象,包含一个数组 state()transition()声明。

创建一个命名的动画触发器

禁用动画

当为 true 时,特殊的动画控件绑定@.disabled绑定会阻止所有动画的渲染。将 @.disabled绑定放在元素上以禁用元素本身的动画,以及元素内的任何内部动画触发器。

@Component({ selector: 'my-component', template: ` <div [@.disabled]="isDisabled"> <div [@childAnimation]="exp"></div> </div> `, animations: [ trigger("childAnimation", [ // ... ]) ] }) class MyComponent { isDisabled = true; exp = '...'; }

另一种方式禁用

@HostBinding('@.disabled') public animationsDisabled = true;

如果 DOM 的某个区域(或整个应用程序)禁用了动画,动画触发器回调仍会触发,但持续时间为零。

state()

附加到元素的触发器中声明动画状态。

state('default', style({opacity: 1})), transition()

满足特定指定条件时播放的动画过渡。

  • 第一个参数: 变化表达式

fromState => toState,这表示应该发生转换的动画(a=>b) transition('open => closed', animate('.5s ease-out', style({ height: 0 }) )) fromState <=> toState,这表示应该发生转换的动画,(a<=>b) transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))

  • :enter/ :leave 当元素显示/隐藏DOM时,出现过渡动画, 产生过渡动画(*ngIf)

transition(':enter', [ style({ opacity: 0 , background: '#e53131'}), animate('1500ms', style({ opacity: 1, background: '#6b6cc5' })) ]) transition(':leave', [ style({ opacity: 0 , background: '#e53131'}), animate('1500ms', style({opacity: 1, background: '#6b6cc5'})) ])

<div [@enabledStateChange]="num" *ngIf="bool"> 内容 </div>

  • :increment/ :decrement,表示当绑定到触发器元素的数值表达式的值增加或减少时,应该发生过渡动画

transition(':increment', animate('1s ease', keyframes([ style({ transform: 'scale(1)', offset: 0}), style({ transform: 'scale(1.1)', offset: 0.7}), style({ transform: 'scale(1)', offset: 1}) ]))), transition(':decrement', animate('1s ease', keyframes([ style({ transform: 'scale(1)', offset: 0}), style({ transform: 'scale(1.1)', offset: 0.7}), style({ transform: 'scale(1)', offset: 1}) ]))),

<div [@enabledStateChange]="num"> 内容 </div> ++num --num

  • 用逗号分割,来表达多个条件

    transition(':increment, * => enabled, :enter', ... )

  • void 元素的缺失

    * 匹配任意状态

    void => * 等价于 :enter dom显示

    * => void 等价于 :leave dom删除

    true并且false还分别匹配和的表达式值10但不匹配,和其他真假值)

query

在序列中动画的当前元素中查找一个或多个内部元素。与 一起使用animate()

query(selector:string,animation: AnimationMetadata | AnimationMetadata[])

selector 类型 string 要查询的元素

Angular动画教程(一)有哪些内容?

query(":enter") 或者 query(":leave") 查询 显示/删除的元素

query(":animating") 查询所有当前动画元素

query("@triggerName") 查询所有动画元素

query("@*"):查询所有包含动画触发器的元素。

query(":self"):将当前元素包含到动画序列中。

多个条件

query(':self, .record:enter, .record:leave, @subTrigger',)

demo

trigger('queryAnimation', [ transition('* => goAnimate', [ // 隐藏内部元素 query('h1', style({ opacity: 0 })), query('.content', style({ opacity: 0 })), // 将内部元素动画化,一个接一个 query('h1', animate(1000, style({ opacity: 1 }))), query('.content', animate(1000, style({ opacity: 1 }))), ]) ])

<div [@queryAnimation]="exp"> <h1>Title</h1> <div class="content"> Blah blah blah </div> </div> <button (click)="exp='goAnimate'">goAnimate</button> animate

参数

  • 第一个参数

    type AnimateTimings = { duration: number; 持续时间 delay: number; 延迟时间 easing: string | null; };

  • animate(500):持续时间为 500 毫秒。
  • animate("1s"): 持续时间为 1000 毫秒。
  • animate("100ms 0.5s"): 持续时间为 100 毫秒,延迟为 500 毫秒。
  • animate("5s ease-in"): 持续时间为 5000 毫秒,渐进式。
  • animate("5s 10ms cubic-bezier(.17,.67,.88,.1)"): 持续时间为 5000 毫秒,延迟为 10 毫秒,根据贝塞尔曲线缓动。
group

动画列表组

group([ animate("1s", style({ background: "black" })), animate("2s", style({ color: "white" })) ]) 参数的使用 transition( '1 => 0', [ style({ height: '0', overflow: 'hidden', }), group([ query('@*', animateChild(), { optional: true }), animate( '{{ duration }}ms {{ delay }}ms {{ ease }}', style({ overflow: 'hidden', height: "*", }), ), ]), ], { params: { duration: 150, delay: '0', ease: 'ease-out' } }, ) 折叠动画

import { animate,animateChild,AnimationTriggerMetadata,group,query,state,style,transition, trigger} from '@angular/animations'; /* usage: [@tdCollapse]="{ value: true | false, params: { duration: 500 }}" */ export const tdCollapseAnimation: AnimationTriggerMetadata = trigger('tdCollapse', [ state('0', style({ height: '*', overflow: '*' })), state('1', style({ height: '0', overflow: 'hidden' })), transition('0 => 1', [ style({overflow: 'hidden', height: '*'}), group([ query('@*', animateChild(), {optional: true}), animate('{{duration}}ms {{delay}}ms {{ease}}', style({height: '0', overflow: 'hidden'})), ]) ], {params: {duration: 150, delay: '0', ease: 'ease-in'}}), transition('1 => 0', [ style({height: '0', overflow: 'hidden'}), group([ query('@*', animateChild(), {optional: true}), animate( '{{duration}}ms {{delay}}ms {{ease}}', style({overflow: 'hidden', height: '*'}) ) ]) ], {params: {duration: 150, delay: '0', ease: 'ease-out'}},) ])

html

<div [@tdCollapse]="{ value: triggerState, params: { duration: 500 }}"> <div style="background: #c45a5a;height: 400px;"></div> </div> <button (click)="triggerState=!triggerState">Click</button>

@Component({ ... animations: [ tdCollapseAnimation ] }) triggerState: boolean = true; 逻辑解释

{optional:true} 是可选的意思, 就是如果传递参数用传递的参数,没有就用默认的

就是如果[@tdCollapse]="{ value: triggerState, params: { duration: 500 }}" 传入了,就用它的

query('@*', animateChild(), {optional: true}), 这个动画或者子代都遵循这套规则

我们知道来个原生的例子方便我们理解,我们知道我们在使用折腾动画需要确认一个高度, 或者使用js动画,计算子代的高度,从而产生过渡的效果

.yl-fb-hide { transition: max-height .3s; max-height: 0; overflow: hidden; } .yl-fb-show { overflow: auto; max-height: 1000px; animation: hide-scroll .3s backwards; } @keyframes hide-scroll { from{ max-height: 0; overflow:hidden; } to{ max-height: 1000px; overflow:hidden; } }

transition('0 => 1', [ style({overflow: 'hidden', height: '*'}), group([ query('@*', animateChild(), {optional: true}), animate('{{duration}}ms {{delay}}ms {{ease}}', style({height: '0', overflow: 'hidden'})), ]) ], {params: {duration: 150, delay: '0', ease: 'ease-in'}}),

可能我们疑惑0 => 1 中为啥要在默认设置 style({overflow: 'hidden', ...}),

其实这个作用是为了本盒子计算出当前盒子的高度, 从而实现收起动画的过渡

决定自己的高度的是你的态度,而不是你的才能 记得我们是终身初学者和学习者

总有一天我也能成为大佬

本文共计1931个文字,预计阅读时间需要8分钟。

Angular动画教程(一)有哪些内容?

访问以下链接,查看Angular动画探索器的示例:

[https://williamjuan027.github.io/angular-animations-explorer/home](https://williamjuan027.github.io/angular-animations-explorer/home)

使用`BrowserAnimationsModule`模块,以下是一个简单的组件示例,包含动画:

typescript@Component({ selector: 'app-animation-example', templateUrl: './animation-example.component.', styleUrls: ['./animation-example.component.css'], animations: [ trigger('enabledStateChange', [ state('default', style({ opacity: 1 })), state('disabled', style({ opacity: 0.5 })), transition('default=> disabled', animate('300ms')), transition('disabled=> default', animate('300ms')) ]) ]})export class AnimationExampleComponent { // 组件逻辑}

williamjuan027.github.io/angular-animations-explorer/home

注入模块

BrowserAnimationsModule 来个小案例

@Component({ ... animations: [ trigger('enabledStateChange', [ state('default', style({opacity: 1})), state('disabled', style({opacity: .5, background: '#000'})), transition('* => *', animate('1500ms ease-out')) ]), ] }) stateOfElement = 'default'; toggleMethod() { this.stateOfElement = this.stateOfElement === 'default' ? 'disabled' : "default" }

<div [@enabledStateChange]="stateOfElement"></div> <button (click)="toggleMethod()">Click</button> trigger

trigger(name: string, definitions: AnimationMetadata[]): AnimationTriggerMetadata 参数 name string 一个标识字符串。 definitions AnimationMetadata[] 一个动画定义对象,包含一个数组 state()transition()声明。

创建一个命名的动画触发器

禁用动画

当为 true 时,特殊的动画控件绑定@.disabled绑定会阻止所有动画的渲染。将 @.disabled绑定放在元素上以禁用元素本身的动画,以及元素内的任何内部动画触发器。

@Component({ selector: 'my-component', template: ` <div [@.disabled]="isDisabled"> <div [@childAnimation]="exp"></div> </div> `, animations: [ trigger("childAnimation", [ // ... ]) ] }) class MyComponent { isDisabled = true; exp = '...'; }

另一种方式禁用

@HostBinding('@.disabled') public animationsDisabled = true;

如果 DOM 的某个区域(或整个应用程序)禁用了动画,动画触发器回调仍会触发,但持续时间为零。

state()

附加到元素的触发器中声明动画状态。

state('default', style({opacity: 1})), transition()

满足特定指定条件时播放的动画过渡。

  • 第一个参数: 变化表达式

fromState => toState,这表示应该发生转换的动画(a=>b) transition('open => closed', animate('.5s ease-out', style({ height: 0 }) )) fromState <=> toState,这表示应该发生转换的动画,(a<=>b) transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))

  • :enter/ :leave 当元素显示/隐藏DOM时,出现过渡动画, 产生过渡动画(*ngIf)

transition(':enter', [ style({ opacity: 0 , background: '#e53131'}), animate('1500ms', style({ opacity: 1, background: '#6b6cc5' })) ]) transition(':leave', [ style({ opacity: 0 , background: '#e53131'}), animate('1500ms', style({opacity: 1, background: '#6b6cc5'})) ])

<div [@enabledStateChange]="num" *ngIf="bool"> 内容 </div>

  • :increment/ :decrement,表示当绑定到触发器元素的数值表达式的值增加或减少时,应该发生过渡动画

transition(':increment', animate('1s ease', keyframes([ style({ transform: 'scale(1)', offset: 0}), style({ transform: 'scale(1.1)', offset: 0.7}), style({ transform: 'scale(1)', offset: 1}) ]))), transition(':decrement', animate('1s ease', keyframes([ style({ transform: 'scale(1)', offset: 0}), style({ transform: 'scale(1.1)', offset: 0.7}), style({ transform: 'scale(1)', offset: 1}) ]))),

<div [@enabledStateChange]="num"> 内容 </div> ++num --num

  • 用逗号分割,来表达多个条件

    transition(':increment, * => enabled, :enter', ... )

  • void 元素的缺失

    * 匹配任意状态

    void => * 等价于 :enter dom显示

    * => void 等价于 :leave dom删除

    true并且false还分别匹配和的表达式值10但不匹配,和其他真假值)

query

在序列中动画的当前元素中查找一个或多个内部元素。与 一起使用animate()

query(selector:string,animation: AnimationMetadata | AnimationMetadata[])

selector 类型 string 要查询的元素

Angular动画教程(一)有哪些内容?

query(":enter") 或者 query(":leave") 查询 显示/删除的元素

query(":animating") 查询所有当前动画元素

query("@triggerName") 查询所有动画元素

query("@*"):查询所有包含动画触发器的元素。

query(":self"):将当前元素包含到动画序列中。

多个条件

query(':self, .record:enter, .record:leave, @subTrigger',)

demo

trigger('queryAnimation', [ transition('* => goAnimate', [ // 隐藏内部元素 query('h1', style({ opacity: 0 })), query('.content', style({ opacity: 0 })), // 将内部元素动画化,一个接一个 query('h1', animate(1000, style({ opacity: 1 }))), query('.content', animate(1000, style({ opacity: 1 }))), ]) ])

<div [@queryAnimation]="exp"> <h1>Title</h1> <div class="content"> Blah blah blah </div> </div> <button (click)="exp='goAnimate'">goAnimate</button> animate

参数

  • 第一个参数

    type AnimateTimings = { duration: number; 持续时间 delay: number; 延迟时间 easing: string | null; };

  • animate(500):持续时间为 500 毫秒。
  • animate("1s"): 持续时间为 1000 毫秒。
  • animate("100ms 0.5s"): 持续时间为 100 毫秒,延迟为 500 毫秒。
  • animate("5s ease-in"): 持续时间为 5000 毫秒,渐进式。
  • animate("5s 10ms cubic-bezier(.17,.67,.88,.1)"): 持续时间为 5000 毫秒,延迟为 10 毫秒,根据贝塞尔曲线缓动。
group

动画列表组

group([ animate("1s", style({ background: "black" })), animate("2s", style({ color: "white" })) ]) 参数的使用 transition( '1 => 0', [ style({ height: '0', overflow: 'hidden', }), group([ query('@*', animateChild(), { optional: true }), animate( '{{ duration }}ms {{ delay }}ms {{ ease }}', style({ overflow: 'hidden', height: "*", }), ), ]), ], { params: { duration: 150, delay: '0', ease: 'ease-out' } }, ) 折叠动画

import { animate,animateChild,AnimationTriggerMetadata,group,query,state,style,transition, trigger} from '@angular/animations'; /* usage: [@tdCollapse]="{ value: true | false, params: { duration: 500 }}" */ export const tdCollapseAnimation: AnimationTriggerMetadata = trigger('tdCollapse', [ state('0', style({ height: '*', overflow: '*' })), state('1', style({ height: '0', overflow: 'hidden' })), transition('0 => 1', [ style({overflow: 'hidden', height: '*'}), group([ query('@*', animateChild(), {optional: true}), animate('{{duration}}ms {{delay}}ms {{ease}}', style({height: '0', overflow: 'hidden'})), ]) ], {params: {duration: 150, delay: '0', ease: 'ease-in'}}), transition('1 => 0', [ style({height: '0', overflow: 'hidden'}), group([ query('@*', animateChild(), {optional: true}), animate( '{{duration}}ms {{delay}}ms {{ease}}', style({overflow: 'hidden', height: '*'}) ) ]) ], {params: {duration: 150, delay: '0', ease: 'ease-out'}},) ])

html

<div [@tdCollapse]="{ value: triggerState, params: { duration: 500 }}"> <div style="background: #c45a5a;height: 400px;"></div> </div> <button (click)="triggerState=!triggerState">Click</button>

@Component({ ... animations: [ tdCollapseAnimation ] }) triggerState: boolean = true; 逻辑解释

{optional:true} 是可选的意思, 就是如果传递参数用传递的参数,没有就用默认的

就是如果[@tdCollapse]="{ value: triggerState, params: { duration: 500 }}" 传入了,就用它的

query('@*', animateChild(), {optional: true}), 这个动画或者子代都遵循这套规则

我们知道来个原生的例子方便我们理解,我们知道我们在使用折腾动画需要确认一个高度, 或者使用js动画,计算子代的高度,从而产生过渡的效果

.yl-fb-hide { transition: max-height .3s; max-height: 0; overflow: hidden; } .yl-fb-show { overflow: auto; max-height: 1000px; animation: hide-scroll .3s backwards; } @keyframes hide-scroll { from{ max-height: 0; overflow:hidden; } to{ max-height: 1000px; overflow:hidden; } }

transition('0 => 1', [ style({overflow: 'hidden', height: '*'}), group([ query('@*', animateChild(), {optional: true}), animate('{{duration}}ms {{delay}}ms {{ease}}', style({height: '0', overflow: 'hidden'})), ]) ], {params: {duration: 150, delay: '0', ease: 'ease-in'}}),

可能我们疑惑0 => 1 中为啥要在默认设置 style({overflow: 'hidden', ...}),

其实这个作用是为了本盒子计算出当前盒子的高度, 从而实现收起动画的过渡

决定自己的高度的是你的态度,而不是你的才能 记得我们是终身初学者和学习者

总有一天我也能成为大佬