2017-09-01 38 views
9

Próbuję replikować tej animacji z Material.io:Jak animować ScrollTop za pomocą @ angle/animations?

Card Animation

Aby poruszać się tylko wysokość jak kliknięcie na pierwszej karcie w powyższym przykładzie jest prosta. Po prostu animuj atrybut wysokości. Problem polega na kliknięciu drugiej karty, a następnie odsuwa pozostałe karty.

Jednym z rozwiązań jest użycie przewijania, aby emulować efekt, który powoduje, że rzeczy zostają odepchnięte. Kliknięcie elementu powoduje zwiększenie jego wysokości przez animowanie wysokości, ale jednocześnie przewijanie widoku.

Mój problem: Nie potrafię wymyślić sposobu animowania zwojów za pomocą @angular/animations. Nie mogę używać style({ scrollTop: 100 }), pozwala to tylko na atrybuty CSS zgodnie z documentation.

Jak to osiągnąć? Byłoby miło, gdybym mógł zrobić to jako część animacji animate() ze względów konserwacyjnych (aby zachować całą animację w 1 miejscu w kodzie), ale jeśli jest to możliwe tylko przy użyciu osobnej metody, to też byłoby to akceptowalne.

Odpowiedz

0

udało mi się stworzyć to, stosując trzy kątowe animacje stwierdza: małe, duży i normalny, co odpowiada wysokości Gr:

animations.ts

Tutaj , Użyłem jednej zmiennej stanu na div jako przykład i ustawiam każdy z tych stanów na normalnie domyślnie. Następnie, w zależności od div kliknę, przełączam stany według tego, co chcemy, aby stało: uczynienie div klikamy na większy i innych mniejszy

export const expand = [ 
    trigger('expand', [ 
    state('big', style({ 
     'height': '200px' 
    })), 
    state('normal', style({ 
     'height': '100px' 
    })), 
    state('small', style({ 
     'height': '50px' 
    })), 
    transition('* => *', [group([ 
     animate(1000) 
    ] 
    )]) 
    ]), 
] 

app.component. ts

import { expand } from './animations'; 

@Component({ 
    ... 
    animations: [expand] 
}) 
export class AppComponent implements OnInit { 
    expandState1 = 'normal'; 
    expandState2 = 'normal'; 
    expandState3 = 'normal'; 
    expandState4 = 'normal'; 
    expandState5 = 'normal'; 

    ngOnInit() { 
    this.resetStates(); 
    } 

    resetStates() { 
    this.expandState1 = 'normal'; 
    this.expandState2 = 'normal'; 
    this.expandState3 = 'normal'; 
    this.expandState4 = 'normal'; 
    this.expandState5 = 'normal'; 
    } 

    toggleShowDiv(divName: string) { 
    if (divName === 'div1') { 
     if (this.expandState1 === 'normal' || this.expandState1 === 'small') { 
     this.setToBig([1]); 
     this.setToSmall([2, 3, 4, 5]); 
     } else if (this.expandState1 === 'big' || this.expandState1 === 'small') { 
     this.resetStates(); 
     } 
    } else if (divName === 'div2') { 
     if (this.expandState2 === 'normal' || this.expandState2 === 'small') { 
     this.setToBig([2]); 
     this.setToSmall([1, 3, 4, 5]); 
     } else if (this.expandState2 === 'big') { 
     this.resetStates(); 
     } 
    } else if (divName === 'div3') { 
     if (this.expandState3 === 'normal' || this.expandState3 === 'small') { 
     this.setToBig([3]); 
     this.setToSmall([1, 2, 4, 5]); 
     } else if (this.expandState3 === 'big') { 
     this.resetStates(); 
     } 
    } else if (divName === 'div4') { 
     if (this.expandState4 === 'normal' || this.expandState4 === 'small') { 
     this.setToBig([4]); 
     this.setToSmall([1, 2, 3, 5]); 
     } else if (this.expandState4 === 'big') { 
     this.resetStates(); 
     } 
    } else if (divName === 'div5') { 
     if (this.expandState5 === 'normal' || this.expandState5 === 'small') { 
     this.setToBig([5]); 
     this.setToSmall([1, 2, 3, 4]); 
     } else if (this.expandState5 === 'big') { 
     this.resetStates(); 
     } 
    } 
    } 

    setToSmall(choices: any) { 
    for (let i = 0; i < choices.length; i++) { 
     switch (choices[i]) { 
     case 1: 
      this.expandState1 = 'small'; 
      break; 
     case 2: 
      this.expandState2 = 'small'; 
      break; 
     case 3: 
      this.expandState3 = 'small'; 
      break; 
     case 4: 
      this.expandState4 = 'small'; 
      break; 
     case 5: 
      this.expandState5 = 'small'; 
      break; 
     default: 
      break; 
     } 
    } 
    } 

    setToBig(choices: any) { 
    for (let i = 0; i < choices.length; i++) { 
     switch (choices[i]) { 
     case 1: 
      this.expandState1 = 'big'; 
      break; 
     case 2: 
      this.expandState2 = 'big'; 
      break; 
     case 3: 
      this.expandState3 = 'big'; 
      break; 
     case 4: 
      this.expandState4 = 'big'; 
      break; 
     case 5: 
      this.expandState5 = 'big'; 
      break; 
     default: 
      break; 
     } 
    } 
    } 
} 

I tu jest odpowiedni szablon:

Każdy div ma odniesienie do th Wyzwalacz animacji [@expand] i jego stan.

<div class="wrapper scrollableDiv"> 
    <div [@expand]="expandState1" (click)="toggleShowDiv('div1')" class="content divA">THIS IS CONTENT DIV 1</div> 
    <div [@expand]="expandState2" (click)="toggleShowDiv('div2')" class="content divA">THIS IS CONTENT DIV 2</div> 
    <div [@expand]="expandState3" (click)="toggleShowDiv('div3')" class="content divA">THIS IS CONTENT DIV 3</div> 
    <div [@expand]="expandState4" (click)="toggleShowDiv('div4')" class="content divA">THIS IS CONTENT DIV 4</div> 
    <div [@expand]="expandState5" (click)="toggleShowDiv('div5')" class="content divA">THIS IS CONTENT DIV 5</div> 
</div> 

Oto przykład StackBlitz zrobiłem tego: https://stackblitz.com/edit/angular-t47iyy