如何创建支持自定义参数及@Input()传入的Angular动画?
实现可传入自定义参数的Angular动画
完全可以实现将组件的@Input()属性传入Angular动画,核心是利用Angular动画的参数化特性,或者通过工厂函数生成定制化动画。以下是两种常用方案:
方案一:模板动态传参(推荐,支持实时变更)
这种方式允许你在模板中绑定动画时,动态传入组件的@Input()属性,参数变化时动画会自动适配新值。
1. 修改动画定义(使用参数占位符)
在animations.ts中,将固定值替换为{{ 参数名 }}的插值语法,并可设置参数默认值:
import { trigger, state, style, transition, animate, group } from '@angular/animations'; export const SlideInOutAnimation = trigger('slideInOut', [ state( 'in', style({ width: '{{ targetWidth }}', opacity: '1', visibility: 'visible', }), { params: { targetWidth: '50%' } } // 设置默认值,不传参数时生效 ), state( 'out', style({ width: '{{ collapsedWidth }}', opacity: 0.3, visibility: 'visible', }), { params: { collapsedWidth: '50px' } } // 默认折叠宽度 ), transition('in => out', [ group([ animate( '{{ duration }} ease-in-out', style({ width: '{{ collapsedWidth }}' }) ), ]), ], { params: { duration: '600ms' } }), transition('out => in', [ group([ animate('1ms ease-in-out', style({ visibility: 'visible' })), animate( '{{ duration }} ease-in-out', style({ width: '{{ targetWidth }}' }) ), animate( '{{ opacityDuration }} ease-in-out', style({ opacity: '1' }) ), ]), ], { params: { duration: '600ms', opacityDuration: '800ms' } }), ]);
2. 组件中定义@Input()属性
在动画组件中声明需要接收的自定义参数:
import { Component, Input } from '@angular/core'; import { SlideInOutAnimation } from './animation'; @Component({ selector: 'app-slide-in-animation', templateUrl: './slide-in-animation.component.html', animations: [SlideInOutAnimation] }) export class SlideInAnimationComponent { @Input() targetWidth = '50%'; // 展开状态宽度,默认与动画默认值一致 @Input() collapsedWidth = '50px'; // 折叠状态宽度 @Input() animationDuration = '600ms'; // 宽度动画时长 @Input() opacityDuration = '800ms'; // 透明度动画时长 currentState = 'out'; toggleState() { this.currentState = this.currentState === 'in' ? 'out' : 'in'; } }
3. 模板绑定动画并传递参数
在组件模板中,通过[@triggerName]的对象形式传递状态和参数,参数直接绑定@Input()属性:
<div class="slide-container" [@slideInOut]="{ value: currentState, params: { targetWidth: targetWidth, collapsedWidth: collapsedWidth, duration: animationDuration, opacityDuration: opacityDuration } }" > <button (click)="toggleState()">切换折叠/展开</button> <!-- 组件内容 --> </div>
4. 父组件中传入自定义参数
在父组件模板中使用动画组件时,直接传入自定义值:
<app-slide-in-animation [targetWidth]="'70%'" [collapsedWidth]="'80px'" [animationDuration]="'800ms'" ></app-slide-in-animation>
方案二:工厂函数生成定制动画(静态配置)
如果不需要动态修改动画参数,可将动画封装成工厂函数,初始化时传入固定参数生成定制化动画:
1. 编写动画工厂函数
// animations.ts import { trigger, state, style, transition, animate, group } from '@angular/animations'; export function createSlideInOutAnimation(defaults: { targetWidth?: string; collapsedWidth?: string; duration?: string; opacityDuration?: string; } = {}) { // 合并默认值与传入参数 const { targetWidth = '50%', collapsedWidth = '50px', duration = '600ms', opacityDuration = '800ms' } = defaults; return trigger('slideInOut', [ state('in', style({ width: targetWidth, opacity: '1', visibility: 'visible', })), state('out', style({ width: collapsedWidth, opacity: 0.3, visibility: 'visible', })), transition('in => out', [ group([animate(`${duration} ease-in-out`, style({ width: collapsedWidth }))]), ]), transition('out => in', [ group([ animate('1ms ease-in-out', style({ visibility: 'visible' })), animate(`${duration} ease-in-out`, style({ width: targetWidth })), animate(`${opacityDuration} ease-in-out`, style({ opacity: '1' })), ]), ]), ]); }
2. 组件中使用工厂函数
import { Component } from '@angular/core'; import { createSlideInOutAnimation } from './animation'; @Component({ selector: 'app-slide-in-animation', templateUrl: './slide-in-animation.component.html', // 初始化时传入定制参数 animations: [createSlideInOutAnimation({ targetWidth: '60%', duration: '700ms' })] }) export class SlideInAnimationComponent { currentState = 'out'; toggleState() { this.currentState = this.currentState === 'in' ? 'out' : 'in'; } }
两种方案对比
- 模板动态传参:支持实时修改参数(比如
@Input()值变化时,动画自动适配),适合需要动态调整的场景。 - 工厂函数方案:参数在组件初始化时固定,后续无法修改,适合配置固定的动画场景。
内容的提问来源于stack exchange,提问作者Ole
相关产品推荐
相关产品推荐

