style: clean up whitespace and formatting in files
This commit is contained in:
parent
2c6be517c1
commit
7de9ef0244
3 changed files with 105 additions and 72 deletions
|
@ -172,12 +172,6 @@ body {
|
|||
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 */
|
||||
#winning-item {
|
||||
z-index: 5; /* Higher than indicator */
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<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 class="loader mb-4"></div>
|
||||
<div class="text-white text-lg">Lade Lootbox...</div>
|
||||
|
@ -7,24 +9,37 @@
|
|||
|
||||
<ng-container *ngIf="!isLoading && lootbox">
|
||||
<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 -->
|
||||
<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>
|
||||
<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 [ngClass]="getRarityClass(reward.probability)" class="text-2xl font-bold mb-1">
|
||||
{{ reward.value | currency:'EUR' }}
|
||||
<div
|
||||
*ngFor="let reward of lootbox.rewards"
|
||||
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 class="text-sm text-white/60">Chance: {{ (reward.probability * 100) | number:'1.0-0' }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Open button -->
|
||||
<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>
|
||||
|
||||
<!-- Loading state -->
|
||||
|
@ -36,59 +51,86 @@
|
|||
<!-- Case opening display - CSGO style -->
|
||||
<div *ngIf="isOpen && !isOpening" class="w-full max-w-lg">
|
||||
<!-- 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-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>
|
||||
|
||||
|
||||
<style>
|
||||
@keyframes fade-in {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<!-- CSGO-style case opening display (horizontal version) -->
|
||||
<div class="case-container">
|
||||
<!-- Central indicator -->
|
||||
<div class="case-indicator"></div>
|
||||
|
||||
|
||||
<!-- Horizontal row of prizes -->
|
||||
<div class="case-items-container">
|
||||
<div class="case-items">
|
||||
<!-- Add a reference element first to help with alignment -->
|
||||
<div class="case-item case-item-ref" style="opacity: 0; pointer-events: none;"></div>
|
||||
|
||||
<div *ngFor="let reward of prizeList; let i = index"
|
||||
class="case-item"
|
||||
[class.case-item-won]="isWonReward(reward)"
|
||||
[id]="isWonReward(reward) ? 'winning-item' : ''"
|
||||
[style.border]="'none'"
|
||||
[style.animation-delay]="isWonReward(reward) ? '10s' : (8 + (i % 50) * 0.04) + 's'">
|
||||
<div class="case-item-inner"
|
||||
[ngClass]="getRarityClass(reward.probability)"
|
||||
[style.border]="''"
|
||||
[style.background-color]="''"
|
||||
[style.transform]="''"
|
||||
[style.box-shadow]="''"
|
||||
[style.margin-left]="isWonReward(reward) ? getCenterOffset() : '0'"
|
||||
[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 class="case-item case-item-ref" style="opacity: 0; pointer-events: none"></div>
|
||||
|
||||
<div
|
||||
*ngFor="let reward of prizeList; let i = index"
|
||||
class="case-item"
|
||||
[class.case-item-won]="isWonReward(reward)"
|
||||
[id]="isWonReward(reward) ? 'winning-item' : ''"
|
||||
[style.border]="'none'"
|
||||
[style.animation-delay]="isWonReward(reward) ? '10s' : 8 + (i % 50) * 0.04 + 's'"
|
||||
>
|
||||
<div
|
||||
class="case-item-inner"
|
||||
[style.border]="''"
|
||||
[style.background-color]="''"
|
||||
[style.transform]="''"
|
||||
[style.box-shadow]="''"
|
||||
[style.margin-left]="isWonReward(reward) ? getCenterOffset() : '0'"
|
||||
[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>
|
||||
|
||||
|
||||
<!-- 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>
|
||||
|
||||
|
||||
<!-- 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;">
|
||||
<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
|
||||
class="flex gap-4 justify-center mt-8"
|
||||
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>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -19,13 +19,13 @@ function shuffle<T>(array: T[]): T[] {
|
|||
standalone: true,
|
||||
imports: [CommonModule, NavbarComponent],
|
||||
templateUrl: './lootbox-opening.component.html',
|
||||
styleUrls: ['./lootbox-opening.component.css']
|
||||
styleUrls: ['./lootbox-opening.component.css'],
|
||||
})
|
||||
export default class LootboxOpeningComponent {
|
||||
lootbox: LootBox | null = null;
|
||||
isLoading = true;
|
||||
error = '';
|
||||
|
||||
|
||||
// UI State
|
||||
isOpening = false;
|
||||
isOpen = false;
|
||||
|
@ -47,7 +47,7 @@ export default class LootboxOpeningComponent {
|
|||
const lootboxId = parseInt(idParam, 10);
|
||||
this.lootboxService.getAllLootBoxes().subscribe({
|
||||
next: (lootboxes) => {
|
||||
this.lootbox = lootboxes.find(box => box.id === lootboxId) || null;
|
||||
this.lootbox = lootboxes.find((box) => box.id === lootboxId) || null;
|
||||
this.isLoading = false;
|
||||
this.cdr.detectChanges();
|
||||
},
|
||||
|
@ -55,7 +55,7 @@ export default class LootboxOpeningComponent {
|
|||
this.error = 'Failed to load lootbox data';
|
||||
this.isLoading = false;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ export default class LootboxOpeningComponent {
|
|||
this.wonReward = null;
|
||||
this.prizeList = []; // Clear previous prizes
|
||||
this.cdr.detectChanges();
|
||||
|
||||
|
||||
// Short delay to ensure animation plays from the beginning
|
||||
setTimeout(() => {
|
||||
this.lootboxService.purchaseLootBox(this.lootbox!.id).subscribe({
|
||||
|
@ -86,21 +86,21 @@ export default class LootboxOpeningComponent {
|
|||
this.isOpening = false;
|
||||
this.isOpen = true;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
},
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
generateCasePrizes(wonReward: Reward) {
|
||||
if (!this.lootbox) return;
|
||||
|
||||
|
||||
// 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 winningPosition = Math.floor(prizeCount / 2); // Position of the winning prize (middle)
|
||||
|
||||
|
||||
// Get possible rewards from the lootbox
|
||||
const possibleRewards = this.lootbox.rewards;
|
||||
|
||||
|
||||
// Generate an array of random rewards
|
||||
let items: Reward[] = [];
|
||||
for (let i = 0; i < prizeCount; i++) {
|
||||
|
@ -114,15 +114,15 @@ export default class LootboxOpeningComponent {
|
|||
items.push(randomReward);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.prizeList = items;
|
||||
}
|
||||
|
||||
|
||||
getWeightedRandomReward(rewards: Reward[]): Reward {
|
||||
// Create a weighted distribution based on probabilities
|
||||
const totalProbability = rewards.reduce((sum, reward) => sum + reward.probability, 0);
|
||||
const randomValue = Math.random() * totalProbability;
|
||||
|
||||
|
||||
let cumulativeProbability = 0;
|
||||
for (const reward of rewards) {
|
||||
cumulativeProbability += reward.probability;
|
||||
|
@ -130,7 +130,7 @@ export default class LootboxOpeningComponent {
|
|||
return { ...reward }; // Return a copy of the reward
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fallback, should never reach here
|
||||
return { ...rewards[0] };
|
||||
}
|
||||
|
@ -151,29 +151,26 @@ export default class LootboxOpeningComponent {
|
|||
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 {
|
||||
if (!this.wonReward) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return reward.id === this.wonReward.id &&
|
||||
reward.value === this.wonReward.value &&
|
||||
reward.probability === this.wonReward.probability;
|
||||
|
||||
return (
|
||||
reward.id === this.wonReward.id &&
|
||||
reward.value === this.wonReward.value &&
|
||||
reward.probability === this.wonReward.probability
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Calculate the center position for better alignment
|
||||
getCenterOffset(): string {
|
||||
return '0px'; // No additional offset - using animation transform instead
|
||||
}
|
||||
|
||||
|
||||
// Check if item is at center position (100th item)
|
||||
isCenterItem(index: number): boolean {
|
||||
return index === Math.floor(200 / 2); // Center item at index 100 (0-indexed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue