【问题标题】:Angular CDK: Apply animations to Angular custom stepper on step changeAngular CDK:在步骤更改时将动画应用于 Angular 自定义步进器
【发布时间】:2019-09-19 14:08:43
【问题描述】:

我一直坚持使用 CDK 为 Angular 材质自定义步进器的步进变化设置动画。 我已经按照tutorial 了解如何实现自定义步进器。

我有演示here

我的模板看起来像:

<section class="container">
 <header>
    <h2>Step {{selectedIndex + 1}}/{{steps.length}}</h2>
    <div>
      <button class="pure-button" cdkStepperPrevious>&larr;</button>
      <button
      class="pure-button"
      *ngFor="let step of steps; let i = index;"
      [ngClass]="{'pure-button-primary': selectedIndex === i}"
      (click)="onClick(i)"
  >
    Step {{i + 1}}
      </button>
      <button class="pure-button" cdkStepperNext>&rarr;</button>
     </div>
   </header>

 <div [@stepTransition]="_getAnimationDirection(current)" *ngFor="let step of _steps; let i = index">
  <div  [ngTemplateOutlet]="selected.content"></div>
  </div>

</section>

我的组件 TS 文件看起来像:

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

 @Component({
   selector: 'app-my-stepper',
   templateUrl: './my-stepper.component.html',
   styleUrls: ['./my-stepper.component.css'],
   providers: [{ provide: CdkStepper, useExisting: MyStepperComponent }],
  animations: [trigger('stepTransition', [
      state('previous', style({transform: 'translate3d(-100%, 0, 0)', visibility: 'hidden'})),
      state('current', style({transform: 'none', visibility: 'visible'})),
      state('next', style({transform: 'translate3d(100%, 0, 0)', visibility: 'hidden'})),
      transition('* => *', animate('500ms cubic-bezier(0.35, 0, 0.25, 1)'))
   ])]
})
 export class MyStepperComponent extends CdkStepper implements OnInit {
    current = 0;

    onClick(index: number): void {
    this.current = index;
     this.selectedIndex = index;
  }

  ngOnInit() {   
      console.log(this._getFocusIndex())
   }

}

动画只对最后一步起作用,原因是动画状态(previous, current, next)值在onClick时没有变化。

我怎样才能做到这一点?任何想法都非常感谢,谢谢。

更新 查看 stackblitz repo 以获取最新代码

【问题讨论】:

    标签: angular angular-material angular-animations angular-cdk


    【解决方案1】:

    在您的 stackblitz demo 中,您有以下 html:

    <div *ngFor="let step of _steps; let i = index"
         [@stepTransition]="_getAnimationDirection(i)" 
         [attr.tabindex]="selectedIndex === i ? 0 : null"
         [id]="_getStepContentId(i)"
         (@stepTransition.done)="_animationDone.next($event)"
         [attr.aria-labelledby]="_getStepLabelId(i)"
         [attr.aria-expanded]="selectedIndex === i">
        <ng-container [ngTemplateOutlet]="selected.content">
        </ng-container> 
    </div>
    

    我认为这里的主要问题在于这一行:&lt;div [ngTemplateOutlet]="selected.content"&gt;&lt;/div&gt;

    您为每个step 创建一个div,每个div 将包含相同的selected.content。所以应用于父 divtransformvisibility)的所有样式也将应用于 selected.content,这将导致模棱两可的行为。

    如果您将其替换为&lt;div [ngTemplateOutlet]="step.content"&gt;&lt;/div&gt;,您将开始看到您的所有图像,但它们将被放置在另一个之下。

    这是因为 css visibility 属性:

    它显示或隐藏元素不改变布局 文件。

    所以我建议你在步骤中添加position: absolute;

    看看stackblitz 的这些改进

    【讨论】:

    • 第一次渲染第一个图像时,最后一个图像被滑动,是否有可能第一次完全不可见最后一个图像?
    • @Teebo 是的,您可以在此行之前将transition(':enter', animate(0)), 添加到您的动画中:transition('* =&gt; *', animate('500ms cubic-bezier(0.35, 0, 0.25, 1)'))。它将跳过初始动画。检查更新的 stackblitz。
    • 效果很好!非常感谢你帮助我,我真的很感激。
    • @Teebo 我很高兴能帮上忙!
    猜你喜欢
    • 2019-10-26
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多