style: clean up whitespace and formatting in files

This commit is contained in:
Jan K9f 2025-04-23 14:33:06 +02:00
parent 2c6be517c1
commit 7de9ef0244
Signed by: jank
GPG key ID: 22BEAC760B3333D6
3 changed files with 105 additions and 72 deletions

View file

@ -172,12 +172,6 @@ body {
animation: highlight-winner 1s ease-out 10s forwards; animation: highlight-winner 1s ease-out 10s forwards;
} }
.case-item-won .case-item-inner {
box-shadow: 0 0 15px rgba(255, 255, 255, 0.3);
background: linear-gradient(to right, #232c43, #2a3354, #232c43);
border: 2px solid #facc15; /* Gold border for winning item */
}
/* Specific ID for the winning item to ensure it's visible */ /* Specific ID for the winning item to ensure it's visible */
#winning-item { #winning-item {
z-index: 5; /* Higher than indicator */ z-index: 5; /* Higher than indicator */

View file

@ -1,5 +1,7 @@
<app-navbar></app-navbar> <app-navbar></app-navbar>
<div class="flex flex-col items-center min-h-screen bg-gradient-to-b from-[#181c2a] to-[#232c43] py-10"> <div
class="flex flex-col items-center min-h-screen bg-gradient-to-b from-[#181c2a] to-[#232c43] py-10"
>
<div *ngIf="isLoading" class="flex flex-col items-center justify-center h-96"> <div *ngIf="isLoading" class="flex flex-col items-center justify-center h-96">
<div class="loader mb-4"></div> <div class="loader mb-4"></div>
<div class="text-white text-lg">Lade Lootbox...</div> <div class="text-white text-lg">Lade Lootbox...</div>
@ -7,24 +9,37 @@
<ng-container *ngIf="!isLoading && lootbox"> <ng-container *ngIf="!isLoading && lootbox">
<h1 class="text-3xl font-bold text-white mb-2">{{ lootbox.name }}</h1> <h1 class="text-3xl font-bold text-white mb-2">{{ lootbox.name }}</h1>
<div class="text-lg text-blue-300 mb-6">Preis: {{ lootbox.price | currency:'EUR' }}</div> <div class="text-lg text-blue-300 mb-6">Preis: {{ lootbox.price | currency: 'EUR' }}</div>
<!-- Before opening - show possible rewards --> <!-- Before opening - show possible rewards -->
<div *ngIf="!isOpening && !isOpen" class="bg-[#1a1f30] p-6 rounded-lg shadow-lg w-full max-w-3xl mb-8"> <div
*ngIf="!isOpening && !isOpen"
class="bg-[#1a1f30] p-6 rounded-lg shadow-lg w-full max-w-3xl mb-8"
>
<h2 class="text-xl font-semibold text-white mb-4">Mögliche Gewinne:</h2> <h2 class="text-xl font-semibold text-white mb-4">Mögliche Gewinne:</h2>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4"> <div class="grid grid-cols-2 md:grid-cols-3 gap-4">
<div *ngFor="let reward of lootbox.rewards" class="bg-[#232c43] p-4 rounded-lg border border-[#2d3748] text-center"> <div
<div [ngClass]="getRarityClass(reward.probability)" class="text-2xl font-bold mb-1"> *ngFor="let reward of lootbox.rewards"
{{ reward.value | currency:'EUR' }} class="bg-[#232c43] p-4 rounded-lg border border-[#2d3748] text-center"
>
<div class="text-2xl font-bold mb-1">
{{ reward.value | currency: 'EUR' }}
</div>
<div class="text-sm text-white/60">
Chance: {{ reward.probability * 100 | number: '1.0-0' }}%
</div> </div>
<div class="text-sm text-white/60">Chance: {{ (reward.probability * 100) | number:'1.0-0' }}%</div>
</div> </div>
</div> </div>
</div> </div>
<!-- Open button --> <!-- Open button -->
<div *ngIf="!isOpening && !isOpen" class="flex flex-col items-center mb-8"> <div *ngIf="!isOpening && !isOpen" class="flex flex-col items-center mb-8">
<button (click)="openLootbox()" class="open-btn text-white px-8 py-3 rounded-lg font-bold text-lg shadow-lg transition-all">Öffnen</button> <button
(click)="openLootbox()"
class="open-btn text-white px-8 py-3 rounded-lg font-bold text-lg shadow-lg transition-all"
>
Öffnen
</button>
</div> </div>
<!-- Loading state --> <!-- Loading state -->
@ -36,59 +51,86 @@
<!-- Case opening display - CSGO style --> <!-- Case opening display - CSGO style -->
<div *ngIf="isOpen && !isOpening" class="w-full max-w-lg"> <div *ngIf="isOpen && !isOpening" class="w-full max-w-lg">
<!-- Winner display - only shown after animation completes --> <!-- Winner display - only shown after animation completes -->
<div class="flex flex-col items-center mb-6" style="opacity: 0; animation: fade-in 0.5s ease-out 10.5s forwards;"> <div
class="flex flex-col items-center mb-6"
style="opacity: 0; animation: fade-in 0.5s ease-out 10.5s forwards"
>
<div class="text-2xl font-bold text-green-400 mb-2">Dein Gewinn:</div> <div class="text-2xl font-bold text-green-400 mb-2">Dein Gewinn:</div>
<div class="text-4xl font-bold text-white mb-4">{{ wonReward?.value | currency:'EUR' }}</div> <div class="text-4xl font-bold text-white mb-4">
{{ wonReward?.value | currency: 'EUR' }}
</div>
</div> </div>
<style> <style>
@keyframes fade-in { @keyframes fade-in {
from { opacity: 0; transform: translateY(10px); } from {
to { opacity: 1; transform: translateY(0); } opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
} }
</style> </style>
<!-- CSGO-style case opening display (horizontal version) --> <!-- CSGO-style case opening display (horizontal version) -->
<div class="case-container"> <div class="case-container">
<!-- Central indicator --> <!-- Central indicator -->
<div class="case-indicator"></div> <div class="case-indicator"></div>
<!-- Horizontal row of prizes --> <!-- Horizontal row of prizes -->
<div class="case-items-container"> <div class="case-items-container">
<div class="case-items"> <div class="case-items">
<!-- Add a reference element first to help with alignment --> <!-- Add a reference element first to help with alignment -->
<div class="case-item case-item-ref" style="opacity: 0; pointer-events: none;"></div> <div class="case-item case-item-ref" style="opacity: 0; pointer-events: none"></div>
<div *ngFor="let reward of prizeList; let i = index" <div
class="case-item" *ngFor="let reward of prizeList; let i = index"
[class.case-item-won]="isWonReward(reward)" class="case-item"
[id]="isWonReward(reward) ? 'winning-item' : ''" [class.case-item-won]="isWonReward(reward)"
[style.border]="'none'" [id]="isWonReward(reward) ? 'winning-item' : ''"
[style.animation-delay]="isWonReward(reward) ? '10s' : (8 + (i % 50) * 0.04) + 's'"> [style.border]="'none'"
<div class="case-item-inner" [style.animation-delay]="isWonReward(reward) ? '10s' : 8 + (i % 50) * 0.04 + 's'"
[ngClass]="getRarityClass(reward.probability)" >
[style.border]="''" <div
[style.background-color]="''" class="case-item-inner"
[style.transform]="''" [style.border]="''"
[style.box-shadow]="''" [style.background-color]="''"
[style.margin-left]="isWonReward(reward) ? getCenterOffset() : '0'" [style.transform]="''"
[style.transition-delay]="(i % 20) * 0.01 + 's'"> [style.box-shadow]="''"
<div class="amount">{{ reward.value | currency:'EUR' }}</div> [style.margin-left]="isWonReward(reward) ? getCenterOffset() : '0'"
<div class="rarity">{{ (reward.probability * 100) | number:'1.0-0' }}%</div> [style.transition-delay]="(i % 20) * 0.01 + 's'"
>
<div class="amount">{{ reward.value | currency: 'EUR' }}</div>
<div class="rarity">{{ reward.probability * 100 | number: '1.0-0' }}%</div>
</div> </div>
</div> </div>
<!-- Add another reference element at the end to help with alignment --> <!-- Add another reference element at the end to help with alignment -->
<div class="case-item case-item-ref" style="opacity: 0; pointer-events: none;"></div> <div class="case-item case-item-ref" style="opacity: 0; pointer-events: none"></div>
</div> </div>
</div> </div>
</div> </div>
<!-- Action buttons - only shown after animation completes --> <!-- Action buttons - only shown after animation completes -->
<div class="flex gap-4 justify-center mt-8" style="opacity: 0; animation: fade-in 0.5s ease-out 10.7s forwards;"> <div
<button (click)="openAgain()" class="open-btn text-white px-6 py-2 rounded-lg font-semibold transition-all">Nochmal öffnen</button> class="flex gap-4 justify-center mt-8"
<button (click)="goBack()" class="bg-[#232c43] hover:bg-[#2d3748] text-white px-6 py-2 rounded-lg font-semibold transition">Zurück zur Übersicht</button> style="opacity: 0; animation: fade-in 0.5s ease-out 10.7s forwards"
>
<button
(click)="openAgain()"
class="open-btn text-white px-6 py-2 rounded-lg font-semibold transition-all"
>
Nochmal öffnen
</button>
<button
(click)="goBack()"
class="bg-[#232c43] hover:bg-[#2d3748] text-white px-6 py-2 rounded-lg font-semibold transition"
>
Zurück zur Übersicht
</button>
</div> </div>
</div> </div>
</ng-container> </ng-container>
</div> </div>

View file

@ -19,13 +19,13 @@ function shuffle<T>(array: T[]): T[] {
standalone: true, standalone: true,
imports: [CommonModule, NavbarComponent], imports: [CommonModule, NavbarComponent],
templateUrl: './lootbox-opening.component.html', templateUrl: './lootbox-opening.component.html',
styleUrls: ['./lootbox-opening.component.css'] styleUrls: ['./lootbox-opening.component.css'],
}) })
export default class LootboxOpeningComponent { export default class LootboxOpeningComponent {
lootbox: LootBox | null = null; lootbox: LootBox | null = null;
isLoading = true; isLoading = true;
error = ''; error = '';
// UI State // UI State
isOpening = false; isOpening = false;
isOpen = false; isOpen = false;
@ -47,7 +47,7 @@ export default class LootboxOpeningComponent {
const lootboxId = parseInt(idParam, 10); const lootboxId = parseInt(idParam, 10);
this.lootboxService.getAllLootBoxes().subscribe({ this.lootboxService.getAllLootBoxes().subscribe({
next: (lootboxes) => { next: (lootboxes) => {
this.lootbox = lootboxes.find(box => box.id === lootboxId) || null; this.lootbox = lootboxes.find((box) => box.id === lootboxId) || null;
this.isLoading = false; this.isLoading = false;
this.cdr.detectChanges(); this.cdr.detectChanges();
}, },
@ -55,7 +55,7 @@ export default class LootboxOpeningComponent {
this.error = 'Failed to load lootbox data'; this.error = 'Failed to load lootbox data';
this.isLoading = false; this.isLoading = false;
this.cdr.detectChanges(); this.cdr.detectChanges();
} },
}); });
} }
@ -66,7 +66,7 @@ export default class LootboxOpeningComponent {
this.wonReward = null; this.wonReward = null;
this.prizeList = []; // Clear previous prizes this.prizeList = []; // Clear previous prizes
this.cdr.detectChanges(); this.cdr.detectChanges();
// Short delay to ensure animation plays from the beginning // Short delay to ensure animation plays from the beginning
setTimeout(() => { setTimeout(() => {
this.lootboxService.purchaseLootBox(this.lootbox!.id).subscribe({ this.lootboxService.purchaseLootBox(this.lootbox!.id).subscribe({
@ -86,21 +86,21 @@ export default class LootboxOpeningComponent {
this.isOpening = false; this.isOpening = false;
this.isOpen = true; this.isOpen = true;
this.cdr.detectChanges(); this.cdr.detectChanges();
} },
}); });
}, 100); }, 100);
} }
generateCasePrizes(wonReward: Reward) { generateCasePrizes(wonReward: Reward) {
if (!this.lootbox) return; if (!this.lootbox) return;
// Create a case opening display with an extremely large number of prizes for a massive scrolling animation // Create a case opening display with an extremely large number of prizes for a massive scrolling animation
const prizeCount = 200; // Set to 200 for an extremely long scrolling animation const prizeCount = 200; // Set to 200 for an extremely long scrolling animation
const winningPosition = Math.floor(prizeCount / 2); // Position of the winning prize (middle) const winningPosition = Math.floor(prizeCount / 2); // Position of the winning prize (middle)
// Get possible rewards from the lootbox // Get possible rewards from the lootbox
const possibleRewards = this.lootbox.rewards; const possibleRewards = this.lootbox.rewards;
// Generate an array of random rewards // Generate an array of random rewards
let items: Reward[] = []; let items: Reward[] = [];
for (let i = 0; i < prizeCount; i++) { for (let i = 0; i < prizeCount; i++) {
@ -114,15 +114,15 @@ export default class LootboxOpeningComponent {
items.push(randomReward); items.push(randomReward);
} }
} }
this.prizeList = items; this.prizeList = items;
} }
getWeightedRandomReward(rewards: Reward[]): Reward { getWeightedRandomReward(rewards: Reward[]): Reward {
// Create a weighted distribution based on probabilities // Create a weighted distribution based on probabilities
const totalProbability = rewards.reduce((sum, reward) => sum + reward.probability, 0); const totalProbability = rewards.reduce((sum, reward) => sum + reward.probability, 0);
const randomValue = Math.random() * totalProbability; const randomValue = Math.random() * totalProbability;
let cumulativeProbability = 0; let cumulativeProbability = 0;
for (const reward of rewards) { for (const reward of rewards) {
cumulativeProbability += reward.probability; cumulativeProbability += reward.probability;
@ -130,7 +130,7 @@ export default class LootboxOpeningComponent {
return { ...reward }; // Return a copy of the reward return { ...reward }; // Return a copy of the reward
} }
} }
// Fallback, should never reach here // Fallback, should never reach here
return { ...rewards[0] }; return { ...rewards[0] };
} }
@ -151,29 +151,26 @@ export default class LootboxOpeningComponent {
this.router.navigate(['/game/lootboxes']); this.router.navigate(['/game/lootboxes']);
} }
getRarityClass(prob: number): string {
if (prob <= 0.1) return 'text-yellow-400 border-yellow-400';
if (prob <= 0.3) return 'text-purple-400 border-purple-400';
return 'text-blue-400 border-blue-400';
}
isWonReward(reward: Reward): boolean { isWonReward(reward: Reward): boolean {
if (!this.wonReward) { if (!this.wonReward) {
return false; return false;
} }
return reward.id === this.wonReward.id && return (
reward.value === this.wonReward.value && reward.id === this.wonReward.id &&
reward.probability === this.wonReward.probability; reward.value === this.wonReward.value &&
reward.probability === this.wonReward.probability
);
} }
// Calculate the center position for better alignment // Calculate the center position for better alignment
getCenterOffset(): string { getCenterOffset(): string {
return '0px'; // No additional offset - using animation transform instead return '0px'; // No additional offset - using animation transform instead
} }
// Check if item is at center position (100th item) // Check if item is at center position (100th item)
isCenterItem(index: number): boolean { isCenterItem(index: number): boolean {
return index === Math.floor(200 / 2); // Center item at index 100 (0-indexed) return index === Math.floor(200 / 2); // Center item at index 100 (0-indexed)
} }
} }