本文介绍了如何使用Angular的ngFor实施项目重新排序/随机播放动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Vue用户很容易实现此类随机播放动画,请参阅其官方文档:

Vue users are easy to implement such item shuffle animations, see their official docs:

我搜索了很多,但找不到Angular用户的解决方案。 ngFor 似乎在切换项目时切换项目内容,而不是移动项目。

I search a lot but can't find a solution for Angular users. ngFor seems to switch item contents instead of moving items when shuffling them.

这是我的演示:

单击shift时,您应该看到项目移动了动画,这要归功于 li {transform:all 1s;} 。但是,当您随机播放它们时,没有动画。因此,我在这里寻求解决方案。

When you click shift, you should see items move animation thanks to li {transform: all 1s;}. But when you shuffle them, there's no animation. So I'm here asking for a solution.

推荐答案

以下是实现此类功能的简单实现

Here is simple implementation such functionality Plunker Example

1)构建指令

@Directive({
  selector: '[transition-group-item]'
})
export class TransitionGroupItemDirective {
  prevPos: any;

  newPos: any;

  el: HTMLElement;

  moved: boolean;

  moveCallback: any;

  constructor(elRef: ElementRef) {
    this.el = elRef.nativeElement;
  }
}


@Component({
  selector: '[transition-group]',
  template: '<ng-content></ng-content>'
})
export class TransitionGroupComponent {
  @Input('transition-group') class;

  @ContentChildren(TransitionGroupItemDirective) items: QueryList<TransitionGroupItemDirective>;

  ngAfterContentInit() {
    this.refreshPosition('prevPos');
    this.items.changes.subscribe(items => {
      items.forEach(item => {
        item.prevPos = item.newPos || item.prevPos;
      });

      items.forEach(this.runCallback);
      this.refreshPosition('newPos');
      items.forEach(this.applyTranslation);

      // force reflow to put everything in position
      const offSet = document.body.offsetHeight;
      this.items.forEach(this.runTransition.bind(this));
    })
  }

  runCallback(item: TransitionGroupItemDirective) {
    if(item.moveCallback) {
      item.moveCallback();
    }
  }

  runTransition(item: TransitionGroupItemDirective) {
    if (!item.moved) {
      return;
    }
    const cssClass = this.class + '-move';
    let el = item.el;
    let style: any = el.style;
    el.classList.add(cssClass);
    style.transform = style.WebkitTransform = style.transitionDuration = '';
    el.addEventListener('transitionend', item.moveCallback = (e: any) => {
      if (!e || /transform$/.test(e.propertyName)) {
        el.removeEventListener('transitionend', item.moveCallback);
        item.moveCallback = null;
        el.classList.remove(cssClass);
      }
    });
  }

  refreshPosition(prop: string) {
    this.items.forEach(item => {
      item[prop] = item.el.getBoundingClientRect();
    });
  }

  applyTranslation(item: TransitionGroupItemDirective) {
    item.moved = false;
    const dx = item.prevPos.left - item.newPos.left;
    const dy = item.prevPos.top - item.newPos.top;
    if (dx || dy) {
      item.moved = true;
      let style: any = item.el.style;
      style.transform = style.WebkitTransform = 'translate(' + dx + 'px,' + dy + 'px)';
      style.transitionDuration = '0s';
    }
  }
}

2)如下使用

<ul [transition-group]="'flip-list'">
  <li *ngFor="let item of items" transition-group-item>
    {{ item }}
  </li>
</ul>

这篇关于如何使用Angular的ngFor实施项目重新排序/随机播放动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 01:31