You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建支持自定义参数及@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:34:53