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
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:
parent
41f3b506a0
commit
09677effe6
4 changed files with 140 additions and 9 deletions
|
@ -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 */
|
||||
}
|
|
@ -2,15 +2,68 @@
|
|||
|
||||
<div class="container mx-auto">
|
||||
<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">
|
||||
<app-game-info
|
||||
[balance]="balance()"
|
||||
[currentBet]="currentBet()"
|
||||
[gameInProgress]="gameInProgress()"
|
||||
[isActionInProgress]="isActionInProgress()"
|
||||
(newGame)="onNewGame($event)"
|
||||
></app-game-info>
|
||||
<div class="card p-4">
|
||||
<h3 class="section-heading text-xl mb-4">Spiel Informationen</h3>
|
||||
<div class="space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-text-secondary">Aktuelle Wette:</span>
|
||||
<span [class]="currentBet() > 0 ? 'text-accent-red' : 'text-text-secondary'">
|
||||
<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>
|
||||
|
|
|
@ -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 { AnimatedNumberComponent } from '@blackjack/components/animated-number/animated-number.component';
|
||||
import { GameInfoComponent } from '@blackjack/components/game-info/game-info.component';
|
||||
import { AuthService } from '@service/auth.service';
|
||||
import { AudioService } from '@shared/services/audio.service';
|
||||
|
@ -6,8 +9,9 @@ import { AudioService } from '@shared/services/audio.service';
|
|||
@Component({
|
||||
selector: 'app-coinflip',
|
||||
standalone: true,
|
||||
imports: [GameInfoComponent],
|
||||
imports: [AnimatedNumberComponent, CurrencyPipe],
|
||||
templateUrl: './coinflip.component.html',
|
||||
styleUrl: './coinflip.component.css',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export default class CoinflipComponent implements OnInit {
|
||||
|
@ -18,9 +22,23 @@ export default class CoinflipComponent implements OnInit {
|
|||
audioService = inject(AudioService);
|
||||
authService = inject(AuthService);
|
||||
|
||||
private http = inject(HttpClient);
|
||||
|
||||
setBetAmount(amount: number) {
|
||||
this.currentBet.update((current) => current * amount);
|
||||
}
|
||||
|
||||
onNewGame(bet: number): void {
|
||||
this.isActionInProgress.set(true);
|
||||
this.audioService.playBetSound();
|
||||
this.currentBet.set(bet);
|
||||
}
|
||||
|
||||
betHeads() {
|
||||
this.gameInProgress.set(true);
|
||||
}
|
||||
betTails() {
|
||||
this.gameInProgress.set(true);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export interface CoinflipGame {
|
||||
isWin: boolean;
|
||||
payout: number;
|
||||
coinSide: string;
|
||||
}
|
Reference in a new issue