File
Implements
Metadata
selector |
app-animation |
styleUrls |
./animation.component.scss |
templateUrl |
./animation.component.html |
Methods
playNextFrame
|
playNextFrame()
|
|
|
board
|
Type : []
|
Default value : []
|
|
board2
|
Type : []
|
Default value : []
|
|
boardCells
|
Type : []
|
Default value : [...Array(10).keys()]
|
|
boardCellsReversed
|
Default value : [...Array(10).keys()].reverse()
|
|
currentBoardRows
|
Type : number
|
Default value : 0
|
|
currentPlay
|
Default value : -1
|
|
rowHeight
|
Type : number
|
Default value : 26
|
|
selectedColor
|
Default value : this.engine.colors[0]
|
|
selectedGameAnimated
|
Type : []
|
Default value : []
|
|
selectedShape
|
Type : []
|
Default value : []
|
|
shape
|
Type : ElementRef
|
Decorators :
@ViewChild('shape')
|
|
showBars
|
Default value : false
|
|
spriteCells
|
Type : []
|
Default value : [...Array(4).keys()]
|
|
spriteCellsReversed
|
Default value : [...Array(4).keys()].reverse()
|
|
table1
|
Type : ElementRef
|
Decorators :
@ViewChild('table1')
|
|
table2
|
Type : ElementRef
|
Decorators :
@ViewChild('table2')
|
|
import { ChangeDetectorRef, Component, ElementRef, OnInit, Renderer2, ViewChild } from '@angular/core';
import { GameEngineService } from 'src/app/services/game-engine.service';
import { gsap, CSSPlugin, TimelineMax } from 'gsap';
gsap.registerPlugin(CSSPlugin, TimelineMax);
@Component({
selector: 'app-animation',
templateUrl: './animation.component.html',
styleUrls: ['./animation.component.scss']
})
export class AnimationComponent implements OnInit {
@ViewChild('shape') shape: ElementRef;
@ViewChild('table1') table1: ElementRef;
@ViewChild('table2') table2: ElementRef;
boardCells = [...Array(10).keys()];
boardCellsReversed = [...Array(10).keys()].reverse();
spriteCells = [...Array(4).keys()];
spriteCellsReversed = [...Array(4).keys()].reverse();
selectedShape = [];
selectedColor = this.engine.colors[0];
board = [];
board2 = [];
currentPlay = -1;
currentBoardRows = 0;
rowHeight = 26;
showBars = false;
selectedGameAnimated = [];
constructor(
public engine: GameEngineService,
private chg: ChangeDetectorRef,
public renderer: Renderer2) { }
ngOnInit() {
const ls = localStorage.getItem('selectedGameAnimated');
this.selectedGameAnimated = JSON.parse(ls);
console.log('ngOnInit');
if (this.selectedGameAnimated) {
setTimeout(() => {
this.playNextFrame();
}, 500);
}
}
playNextFrame() {
if (this.currentPlay >= this.selectedGameAnimated.length + 2) {
this.currentPlay = -1;
this.currentBoardRows = 0;
this.board = [];
this.chg.detectChanges();
}
this.currentPlay++;
const play = this.selectedGameAnimated[this.currentPlay];
if (play) {
let colorIndex = this.currentPlay;
while (colorIndex > this.engine.colors.length - 1) { colorIndex -= this.engine.colors.length; }
const left = play.move[1] * 26;
const topRow = 10 - play.row;
const top = (topRow * this.rowHeight) - 3.51;
const speed = .2 * topRow;
const shape = this.shape.nativeElement;
const shapeAnimation = new TimelineMax({ paused: true })
.to(shape, 0, { opacity: 0, top: -20 + 'px', x: left + 'px' })
.to(shape, 1.5, { opacity: 1 }, .5)
.to(shape, speed, { top: top + 'px', x: left + 'px', ease: 'Expo.easeIn' }, '-=1.5')
.to(shape, 2, {}, 1)
.to(shape, 0, { opacity: 0 })
;
this.selectedColor = this.engine.colors[colorIndex];
this.selectedShape = this.engine.Shapes[play.move[0]];
this.chg.detectChanges();
shapeAnimation.play();
shapeAnimation.eventCallback('onComplete', () => {
this.selectedColor = undefined;
this.selectedShape = [];
this.chg.detectChanges();
if (play?.board?.length > 1) {
const t1 = this.table1.nativeElement;
const t2 = this.table2.nativeElement;
this.renderer.setStyle(t1, 'opacity', 0);
this.renderer.setStyle(t2, 'opacity', 1);
this.board = play.board[1];
this.board2 = play.board[0];
this.currentBoardRows = play.finalRowsAsArray[0];
this.chg.detectChanges();
const boardAnimation = new TimelineMax({ paused: true })
.to(t1, .5, { opacity: 1 })
.to(t2, .5, { opacity: 0 }, .5)
.play();
boardAnimation.eventCallback('onComplete', () => {
this.board2 = [];
this.currentBoardRows = play?.finalRowsAsArray[1];
this.chg.detectChanges();
this.renderer.setStyle(t1, 'opacity', 1);
this.renderer.setStyle(t2, 'opacity', 0);
});
} else {
this.board = play?.board[0];
this.currentBoardRows = play?.finalRowsAsArray[0];
}
this.chg.detectChanges();
this.playNextFrame();
});
} else {
setTimeout(() => { this.playNextFrame(); }, 2000);
}
}
}
<br />
<ng-container *ngIf="this.selectedGameAnimated">
<div style="display: flex; width: 100%; align-content: center">
<div style="margin: 0 auto">
<table style="width: 400px; padding: 10px" class="mat-elevation-z8">
<tr>
<td style="height: 375px; width: 260px">
<div style="position: relative; height: 375px; width: 100%">
<ng-container *ngIf="showBars">
<div style="position: absolute; top: 360px; left: 125px">
{{ currentBoardRows }}
</div>
<!--diagonal bars only -->
<table
*ngIf="showBars"
class="board-table"
cellspacing="0"
cellpadding="0"
>
<tr
*ngFor="let row of boardCellsReversed; let i = index"
[ngClass]="{
'diag-bars': 10 - currentBoardRows <= i
}"
>
<td
*ngFor="let cell of boardCells"
style="border: 1px solid rgba(111, 103, 103, 0)"
class="square-td"
></td>
</tr>
</table>
</ng-container>
<!-- moving shape-->
<table
#shape
style="
padding: 0;
border-collapse: collapse;
position: absolute;
"
cellspacing="0"
cellpadding="0"
>
<tr *ngFor="let row of spriteCellsReversed">
<td
*ngFor="let cell of spriteCells"
class="square-td"
[ngStyle]="{
'background-color': selectedShape.includes(
row * 10 + cell
)
? selectedColor
: '',
border: selectedShape.includes(row * 10 + cell)
? '1px solid rgba(111, 103, 103, 0.65)'
: '1px solid rgba(111, 103, 103, 0.01)'
}"
></td>
</tr>
</table>
<!--board 1 -->
<table
#table1
class="board-table"
cellspacing="0"
cellpadding="0"
>
<tr *ngFor="let row of boardCellsReversed">
<td
class="square-td"
*ngFor="let cell of boardCells"
style="border: 1px solid rgba(111, 103, 103, 0)"
[ngStyle]="{ 'background-color': board[row * 10 + cell] }"
></td>
</tr>
</table>
<table
#table2
class="board-table"
cellspacing="0"
cellpadding="0"
style="opacity: 0"
>
<tr *ngFor="let row of boardCellsReversed">
<td
class="square-td"
*ngFor="let cell of boardCells"
style="border: 1px solid rgba(111, 103, 103, 0)"
[ngStyle]="{ 'background-color': board2[row * 10 + cell] }"
></td>
</tr>
</table>
<!--numbers only -->
<table
class="board-table"
cellspacing="0"
cellpadding="0"
(click)="showBars = !showBars"
>
<tr *ngFor="let row of boardCellsReversed; let i = index">
<td
*ngFor="let cell of boardCells"
style="border: 1px solid rgba(111, 103, 103, 0.65)"
class="bevel square-td"
>
{{ row * 10 + cell }}
</td>
</tr>
</table>
</div>
</td>
<td style="width: 100px; vertical-align: top">
<table style="width: 100%">
<tr
style="
color: white;
background-color: #2b5876;
background-image: linear-gradient(to right, #2b5876, #3f51b5);
"
>
<td>#</td>
<td>Move</td>
<td>Rows</td>
</tr>
<tr
*ngFor="let move of selectedGameAnimated; let i = index"
[ngStyle]="{
'background-color': i == currentPlay ? '#3f51b54a' : ''
}"
class="fader"
>
<td>{{ i + 1 }}.</td>
<td style="text-align: center">{{ move.move }}</td>
<td style="text-align: center">{{ move.finalDisplayRows }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</ng-container>
<div
*ngIf="!this.selectedGameAnimated"
style="padding: 25px; font-size: larger"
>
Loading...
<br /><br />
A game has to be selected from the <a href="/">main app</a> for the animation
to work
</div>
.board-table {
padding: 0;
border-collapse: collapse;
position: absolute;
top: 100px;
left: 0;
}
.square-td {
width: 25px;
min-width: 25px;
max-width: 25px;
height: 25px;
min-height: 25px;
max-height: 25px;
overflow: hidden;
text-align: center;
user-select: none;
cursor: pointer;
}
.fader {
transition: background-color 1s ease-out;
}
.diag-bars {
background: repeating-linear-gradient(
45deg,
transparent,
transparent 10px,
rgba(63, 81, 181, 0.15) 10px,
rgba(63, 81, 181, 0.15) 20px
);
}
Legend
Html element with directive