Im working on a personal project where I have a number of cards and would like to spin through them vertically multiple times and end up on a random card. I'm recreating my project in angular2 and am a little lost on how I would animate the spinning. This is what I have so far...
card.component.ts:
@Component({
selector: 'app-card',
styleUrls: ['./card.component.css'],
templateUrl: './card.component.html',
animations: [
trigger('spinCard', [
state('inactive', style({
transform: 'translateY(0px)'
})),
state('active', style({
transform: 'translateY(100%)'
})),
transition('inactive => active', animate('200ms ease-in-out')),
transition('active => inactive', animate('200ms ease-in-out'))
])
]
})
export class CardComponent {
@Input()
cardState: string;
}
card.component.html:
<div class="card {{cardStyle}}" [@spinCard]="cardState">
<div class="inside-text" id="{{cardId}}">{{cardName}}</div>
</div>
spinner.component.html:
<div class="spinner" id="spinner">
<div class="game-container">
<div class="game-overlay"></div>
<div class="game-area" id="game-area">
<app-card *ngFor="let card of (cards | spinnablePipe: true)" cardState={{cardState}} cardName={{card.name}} cardId={{cardId}} cardStyle={{cardStyle}}></app-card>
</div>
</div>
<div class="spin-layout">
<button type="button" class="spin-btn green-btn" aria-label="Spin" (click)="animateSpin()">
<span>S P I N</span>
</button>
</div>
In native JS, I simply requestAnimationFrame() and change the css and html through JS. However I'm not too sure how to do this the Angular-way.
I'd like to be able to hit a button, the cards would spin within a container and the cards would come to a stop on a random card.
My best idea so far was just to add 5ish sets of identical cards to the container and animate those. I don't think this is a correct approach tho, and also I'm not sure how I would randomize where they'd stop.
Would love some help! Thanks!
try following example for spinning cards
app.component.html
<div class="game-area">
<div class="card" *ngFor="let card of cards" [@cardSpinner]="card.state" [style.background]="card.color">
<p style="font-size: 24px; text-align: center;">{{card.value}}</p>
</div>
</div>
<button type="button" class="spin-btn green-btn" aria-label="Spin" (click)="animateSpin()">
<span>S P I N</span>
</button>
app.component.scss
.game-area {
box-sizing: border-box;
position: relative;
height: 80px;
overflow: hidden;
.card {
bottom: 0;
box-sizing: border-box;
height: 80px;
left: 0;
position: absolute;
right: 0;
width: 80px;
}
}
app.component.ts
import { Component } from '@angular/core';
import { trigger, state, animate, transition,
style } from '@angular/animations';
@Component({
selector: 'ap-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [
trigger('cardSpinner', [
state('in', style({ opacity: 1, transform: 'translateY(0)' })),
state('out', style({ opacity: 0, display: 'none', transform: 'translateY(-100%)' })),
transition('in => out', [
style({ transform: 'translateY(0)', opacity: 1 }),
animate('0.1s', style({ transform: 'translateY(-100%)', opacity: 0 }))
]),
transition('out => in', [
style({ transform: 'translateY(100%)', opacity: 0 }),
animate('0.1s', style({ transform: 'translateY(0)', opacity: 1 }))
])
])
]
})
export class AppComponent {
currentIndex = 0;
intervalInstance;
cards = [
{value: 0, state: 'out', color: '#F44336'},
{value: 1, state: 'out', color: '#E91E63'},
{value: 2, state: 'out', color: '#9C27B0'},
{value: 3, state: 'out', color: '#673AB7'},
{value: 4, state: 'out', color: '#3F51B5'},
{value: 5, state: 'out', color: '#2196F3'},
{value: 6, state: 'out', color: '#03A9F4'},
{value: 7, state: 'out', color: '#00BCD4'},
{value: 8, state: 'out', color: '#009688'},
{value: 9, state: 'out', color: '#4CAF50'}
];
animateSpin() {
this.cards.forEach(card => card.state = 'out');
this.currentIndex = 0;
this.cards[this.currentIndex].state = 'in';
this.intervalInstance = setInterval(() => {
this.currentIndex++;
if (this.currentIndex === this.cards.length) {
this.currentIndex = 0;
}
if (this.currentIndex !== 0 ) {
this.cards[this.currentIndex - 1].state = 'out';
} else {
this.cards[this.cards.length - 1].state = 'out';
}
this.cards[this.currentIndex].state = 'in';
}, 100);
const itemIndex = Math.floor((Math.random() * ((this.cards.length * 5) - this.cards.length)) + this.cards.length);
console.log(itemIndex);
setTimeout(() => {
clearInterval(this.intervalInstance);
const randomCard = this.cards.filter(card => card.state === 'in');
console.log(randomCard);
}, itemIndex * 100);
}
}