2017-05-12 12 views
2

Vueのユーザーが自分の公式ドキュメントを参照して、そのようなアイテムのシャッフルアニメーションを実装するのは簡単です:Angular's ngForでアイテムの並べ替え/シャッフルアニメーションを実装する方法は?

shuffle animation

私は多くのことを検索しますが角度のユーザーのための解決策を見つけることができません。 ngForは、シャッフル時にアイテムを移動するのではなく、アイテムの内容を切り替えているようです。あなたがシフトをクリックすると、あなたはアイテムがli {transform: all 1s;}にアニメーション感謝を移動表示されるはずですhttp://embed.plnkr.co/3IcKcC/

は、ここに私のデモです。しかし、それらをシャッフルすると、アニメーションはありません。だから私はここで解決策を求めている。 HTTPSを:// vuejs

+0

Vueの公式ドキュメントを次のようにそれを使用することです。 org/v2/guide/transitions.html#List-Move-Transitions – Wenris

+1

Angular Animateについて読んだことがありますか?これらの変更を移行するために使用できるのは、 – frosty

+1

'シフトをクリックすると、li {transform:all 1s;}のおかげでアニメーションが動くのが分かります。' vue 'transition-group'のおかげですべて動作します。 – yurzui

答えて

6

は、ここで簡単な実装な機能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> 
+0

あなたはとてもスマートです、それは私が必要とする答えです。簡単に要約すると、アイテムがシャッフルされたときのアイテムの前の位置(0秒)を元に戻し、最後の位置にアニメートします。 – Wenris

関連する問題