befora claude just in case
Some checks failed
CI / Get Changed Files (pull_request) Successful in 7s
CI / Checkstyle Main (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / oxlint (pull_request) Failing after 21s
CI / eslint (pull_request) Failing after 28s
CI / prettier (pull_request) Successful in 27s
CI / test-build (pull_request) Successful in 40s
CI / Docker frontend validation (pull_request) Successful in 1m7s

This commit is contained in:
Jan K9f 2025-05-21 10:32:39 +02:00
commit 09677effe6
4 changed files with 140 additions and 9 deletions

View file

@ -0,0 +1,55 @@
/* Custom CSS for 3D Transformations and Coin Flip (using animation classes) */
@keyframes flipToHeads {
0% {
transform: rotateY(0deg) rotateX(0deg);
}
100% {
transform: rotateX(2880deg) rotateY(1440deg);
}
}
@keyframes flipToTails {
0% {
transform: rotateY(0deg) rotateX(0deg); /* Start with no rotation */
}
100% {
transform: rotateX(-2880deg) rotateY(1620deg); /* Example: Reverse X rotation, and land on tails */
}
}
.coin-container {
width: 150px; /* Set the size of the coin */
height: 150px;
perspective: 1000px; /* Adds 3D perspective */
}
.coin {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d; /* Crucial for 3D transformations */
}
.coin-side {
/* Common styles for both front and back */
width: 100%;
height: 100%;
position: absolute;
backface-visibility: hidden; /* Hide the back of both sides initially */
border-radius: 50%; /* Make it circular */
}
.back {
transform: rotateY(
180deg
); /* Rotate the back to face the opposite direction (Y-axis for horizontal flip) */
}
/* Classes to trigger the specific animation */
.coin.animate-to-heads {
animation: flipToHeads 1s ease-in-out forwards; /* Apply the animation */
}
.coin.animate-to-tails {
animation: flipToTails 1s ease-in-out forwards; /* Apply the animation */
}

View file

@ -2,15 +2,68 @@
<div class="container mx-auto"> <div class="container mx-auto">
<div class="grid grid-cols-4"> <div class="grid grid-cols-4">
<div class="col-span-3"></div> <div class="col-span-3 w-full flex flex-col">
<div class="coin-container mx-auto">
<div id="coin" class="coin animate-to-tails">
<div
class="front coin-side bg-yellow-500 flex items-center justify-center text-2xl font-bold"
>
Heads
</div>
<div
class="back coin-side bg-gray-700 flex items-center justify-center text-2xl font-bold text-white"
>
Tails
</div>
</div>
</div>
<div class="flex gap-3 mt-3 mx-auto">
<button [disabled]="gameInProgress()" class="button-primary py-2 px-4 relative">
Bet tails
</button>
<button [disabled]="gameInProgress()" class="button-primary py-2 px-4 relative">
Bet heads
</button>
</div>
</div>
<div class="col-span-1"> <div class="col-span-1">
<app-game-info <div class="card p-4">
[balance]="balance()" <h3 class="section-heading text-xl mb-4">Spiel Informationen</h3>
[currentBet]="currentBet()" <div class="space-y-4">
[gameInProgress]="gameInProgress()" <div class="flex justify-between items-center">
[isActionInProgress]="isActionInProgress()" <span class="text-text-secondary">Aktuelle Wette:</span>
(newGame)="onNewGame($event)" <span [class]="currentBet() > 0 ? 'text-accent-red' : 'text-text-secondary'">
></app-game-info> <app-animated-number [value]="currentBet()" [duration]="0.5"></app-animated-number>
</span>
</div>
@if (!gameInProgress()) {
<div class="grid grid-cols-2 gap-2 mb-4">
<button (click)="setBetAmount(0.1)" class="button-primary py-2 text-sm">10%</button>
<button (click)="setBetAmount(0.25)" class="button-primary py-2 text-sm">25%</button>
<button (click)="setBetAmount(0.5)" class="button-primary py-2 text-sm">50%</button>
<button (click)="setBetAmount(1)" class="button-primary py-2 text-sm">100%</button>
</div>
}
<form class="space-y-2">
<div class="space-y-1">
<label for="bet" class="text-sm text-text-secondary">Einsatz</label>
<input
type="number"
id="bet"
class="w-full px-3 py-2 bg-deep-blue-light text-white rounded focus:outline-none focus:ring-2 focus:ring-emerald disabled:opacity-50"
[min]="1"
[max]="balance()"
[value]="currentBet()"
step="0.01"
[disabled]="gameInProgress()"
[placeholder]="balance() | currency: 'EUR'"
/>
</div>
</form>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,4 +1,7 @@
import { CurrencyPipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core'; import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';
import { AnimatedNumberComponent } from '@blackjack/components/animated-number/animated-number.component';
import { GameInfoComponent } from '@blackjack/components/game-info/game-info.component'; import { GameInfoComponent } from '@blackjack/components/game-info/game-info.component';
import { AuthService } from '@service/auth.service'; import { AuthService } from '@service/auth.service';
import { AudioService } from '@shared/services/audio.service'; import { AudioService } from '@shared/services/audio.service';
@ -6,8 +9,9 @@ import { AudioService } from '@shared/services/audio.service';
@Component({ @Component({
selector: 'app-coinflip', selector: 'app-coinflip',
standalone: true, standalone: true,
imports: [GameInfoComponent], imports: [AnimatedNumberComponent, CurrencyPipe],
templateUrl: './coinflip.component.html', templateUrl: './coinflip.component.html',
styleUrl: './coinflip.component.css',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export default class CoinflipComponent implements OnInit { export default class CoinflipComponent implements OnInit {
@ -18,9 +22,23 @@ export default class CoinflipComponent implements OnInit {
audioService = inject(AudioService); audioService = inject(AudioService);
authService = inject(AuthService); authService = inject(AuthService);
private http = inject(HttpClient);
setBetAmount(amount: number) {
this.currentBet.update((current) => current * amount);
}
onNewGame(bet: number): void { onNewGame(bet: number): void {
this.isActionInProgress.set(true); this.isActionInProgress.set(true);
this.audioService.playBetSound(); this.audioService.playBetSound();
this.currentBet.set(bet);
}
betHeads() {
this.gameInProgress.set(true);
}
betTails() {
this.gameInProgress.set(true);
} }
ngOnInit(): void { ngOnInit(): void {

View file

@ -0,0 +1,5 @@
export interface CoinflipGame {
isWin: boolean;
payout: number;
coinSide: string;
}