从另一个组件位置动画单个可观察元素

Animate individual observable elements from another component position

我想为单个序列中从起始位置到结束位置的多个元素设置动画(当 card0 完成时,card1 应该开始)。起始位置元素在不同的 Angular 组件中定义。这些卡片在 Observable 元素中定义,当前在您单击按钮时同时显示。

在图像中,您可以看到 card0 应该从 start 移动到底部的 card0 元素。之后,card1 也会发生同样的情况,然后是 card2

我目前只设法为可观察的元素制作动画。我想了解如何分别为它们设置动画以及如何让它们从另一个组件的起始位置开始流动。

这是一个StackBlitz

这有点复杂,因为要将标签从一个位置移动到另一个位置,您需要知道初始位置和最终位置。

假设您有这样的动画:

  animations:[
    trigger('move',[
      transition('false => true',[
      style({ 'top': 0,'left':0 }),
      animate('200ms', style({top:'*',left:'*'})),
    ])])
  ]

此动画将元素从绝对位置 0,0 移动到元素实际拥有的绝对位置。但是我们不想要 style={position:absolute} 的元素。所以我们需要计算。为了计算,我们将获取 ViewChildren 中的元素并使用变量来定位

@ViewChildren('card') cards:QueryList<ElementRef>
pos:any[]=[]

当动画开始时,我们将计算元素的位置。

  startAnimation(){
    this.pos=this.cards.map(x=>{
      const rect=x.nativeElement.getBoundingClientRect();
      return {
         top:(window.scrollY+rect.top)+'px',
         left:(window.scrollX+rect.left)+'px',
         position:'absolute'
      }
    })
    this.count=0;
  }

然后我们将使用变量“count”,当动画完成时增加变量

  animationDone(incr:number)
  {
    this.count+=incr
    if (this.count>3) //<--if the variable is the last animation
      this.pos=this.pos.map(x=>null)  //<--we equal to null the array "pos"
  }

使用可见性隐藏和可见性,使“技巧”

  <div *ngFor="let item of obs$ | async; let i = index">
    <div
      #card
      [ngStyle]="pos[i] || null"
      [style.visibility]="i <= count ? 'visible' : 'hidden'"
      [@move]="count == i"
      (@move.done)="animationDone(count == i ? 1 : 0)"
    >
      {{ item }}
    </div>

您可以在this stackblitz

中看到

注意:看到这个“奇怪”[@move.done]="animationDone(count == i ? 1 : 0)",只在 count==i 时传递给函数 1,否则 Angular 执行这么多次元素具有可观察的