style: Improve CSS formatting and animation adjustments
This commit is contained in:
parent
6f61e6dc3d
commit
f44f5ed02b
3 changed files with 124 additions and 33 deletions
|
@ -33,8 +33,12 @@ body {
|
||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
0% { transform: rotate(0deg); }
|
0% {
|
||||||
100% { transform: rotate(360deg); }
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open button styling */
|
/* Open button styling */
|
||||||
|
@ -65,24 +69,30 @@ body {
|
||||||
.case-indicator {
|
.case-indicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%; /* Back to center - we'll adjust the animation instead */
|
||||||
transform: translateY(-50%);
|
transform: translate(-50%, -50%); /* Center precisely */
|
||||||
width: 6px;
|
width: 4px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: #facc15;
|
background: #ff0000; /* Bright red for debugging */
|
||||||
box-shadow: 0 0 10px #facc15, 0 0 15px rgba(255, 255, 255, 0.5);
|
box-shadow:
|
||||||
|
0 0 10px #ff0000,
|
||||||
|
0 0 15px rgba(255, 0, 0, 0.5);
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
animation: indicator-pulse 1.5s ease-in-out 3s infinite alternate;
|
animation: indicator-pulse 1.5s ease-in-out 10s infinite alternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes indicator-pulse {
|
@keyframes indicator-pulse {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
box-shadow: 0 0 10px #facc15, 0 0 15px rgba(255, 255, 255, 0.3);
|
box-shadow:
|
||||||
|
0 0 10px #ff0000,
|
||||||
|
0 0 15px rgba(255, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
box-shadow: 0 0 15px #facc15, 0 0 20px rgba(255, 255, 255, 0.7);
|
box-shadow:
|
||||||
|
0 0 15px #ff0000,
|
||||||
|
0 0 20px rgba(255, 0, 0, 0.7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +104,9 @@ body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 150px; /* Fixed height for the horizontal row */
|
height: 150px; /* Fixed height for the horizontal row */
|
||||||
overflow: hidden; /* Hide scrollbar */
|
overflow: hidden; /* Hide scrollbar */
|
||||||
|
display: flex;
|
||||||
|
justify-content: center; /* Center the items container */
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-items {
|
.case-items {
|
||||||
|
@ -102,70 +115,123 @@ body {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 5px;
|
padding: 5px 0px; /* Remove horizontal padding */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
animation: slide-in 3s cubic-bezier(0.25, 1, 0.5, 1) forwards;
|
animation: slide-in 10s cubic-bezier(0.05, 0.82, 0.17, 1) forwards;
|
||||||
transform: translateX(120%); /* Initial position far to the right */
|
transform: translateX(3000%); /* Extremely far initial position for 200 items */
|
||||||
|
position: relative; /* Ensure positioning context */
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes slide-in {
|
@keyframes slide-in {
|
||||||
0% {
|
0% {
|
||||||
transform: translateX(120%);
|
transform: translateX(2000%);
|
||||||
}
|
}
|
||||||
90% {
|
90% {
|
||||||
transform: translateX(-5%); /* Slight overshoot */
|
transform: translateX(-16%); /* Single overshoot for dramatic effect */
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: translateX(0%); /* Final centered position */
|
transform: translateX(-8%); /* Centered position */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-item {
|
.case-item {
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
animation: item-flash 0.3s ease-out forwards;
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes item-flash {
|
||||||
|
0% {
|
||||||
|
filter: brightness(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
filter: brightness(1.8);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
filter: brightness(1.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-item-inner {
|
.case-item-inner {
|
||||||
background: #232c43;
|
background: #232c43;
|
||||||
border: 2px solid #2d3748;
|
border: 2px solid #2d3748;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 12px 8px;
|
padding: 10px 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100px;
|
width: 65px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-item-won {
|
.case-item-won {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
animation: highlight-winner 0.5s ease-out 3s forwards;
|
animation: highlight-winner 1s ease-out 10s forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.case-item-won .case-item-inner {
|
.case-item-won .case-item-inner {
|
||||||
box-shadow: 0 0 15px rgba(255, 255, 255, 0.3);
|
box-shadow: 0 0 15px rgba(255, 255, 255, 0.3);
|
||||||
background: linear-gradient(to right, #232c43, #2a3354, #232c43);
|
background: linear-gradient(to right, #232c43, #2a3354, #232c43);
|
||||||
|
border: 3px solid #ff0000 !important; /* Bright red border for debugging */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific ID for the winning item to ensure it's visible */
|
||||||
|
#winning-item {
|
||||||
|
z-index: 5; /* Higher than indicator */
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes highlight-winner {
|
@keyframes highlight-winner {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
|
filter: brightness(1);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: scale(1.3);
|
||||||
|
filter: brightness(2);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
filter: brightness(1.8);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: scale(1.25);
|
||||||
|
filter: brightness(2);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
filter: brightness(1.8);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: scale(1.15);
|
transform: scale(1.25);
|
||||||
|
filter: brightness(2);
|
||||||
}
|
}
|
||||||
75% {
|
60% {
|
||||||
transform: scale(1.1);
|
transform: scale(1.2);
|
||||||
|
filter: brightness(1.8);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(1.25);
|
||||||
|
filter: brightness(2);
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
transform: scale(1.2);
|
||||||
|
filter: brightness(1.8);
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
transform: scale(1.25);
|
||||||
|
filter: brightness(2);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: scale(1.05);
|
transform: scale(1.2);
|
||||||
|
filter: brightness(1.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount {
|
.amount {
|
||||||
font-size: 1.2rem;
|
font-size: 1rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<!-- 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 3.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>
|
||||||
|
@ -56,21 +56,36 @@
|
||||||
<!-- 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 -->
|
||||||
|
<div class="case-item case-item-ref" style="opacity: 0; pointer-events: none;"></div>
|
||||||
|
|
||||||
<div *ngFor="let reward of prizeList; let i = index"
|
<div *ngFor="let reward of prizeList; let i = index"
|
||||||
class="case-item"
|
class="case-item"
|
||||||
[class.case-item-won]="isWonReward(reward)">
|
[class.case-item-won]="isWonReward(reward)"
|
||||||
|
[id]="isWonReward(reward) ? 'winning-item' : ''"
|
||||||
|
[style.border]="isCenterItem(i) ? '3px solid #00ff00' : 'none'"
|
||||||
|
[style.animation-delay]="isWonReward(reward) ? '10s' : (8 + (i % 50) * 0.04) + 's'">
|
||||||
<div class="case-item-inner"
|
<div class="case-item-inner"
|
||||||
[ngClass]="getRarityClass(reward.probability)">
|
[ngClass]="getRarityClass(reward.probability)"
|
||||||
<div class="amount">{{ reward.value | currency:'EUR' }}</div>
|
[style.border]="isCenterItem(i) ? '5px solid lime' : ''"
|
||||||
<div class="rarity">{{ (reward.probability * 100) | number:'1.0-0' }}%</div>
|
[style.background-color]="isCenterItem(i) ? '#004400' : ''"
|
||||||
|
[style.transform]="isCenterItem(i) ? 'scale(1.1)' : ''"
|
||||||
|
[style.box-shadow]="isCenterItem(i) ? '0 0 15px lime' : ''"
|
||||||
|
[style.margin-left]="isWonReward(reward) ? getCenterOffset() : '0'"
|
||||||
|
[style.transition-delay]="(i % 20) * 0.01 + 's'">
|
||||||
|
<div class="amount" [style.color]="isCenterItem(i) ? '#00ff00' : ''">{{ reward.value | currency:'EUR' }}</div>
|
||||||
|
<div class="rarity" [style.color]="isCenterItem(i) ? '#00ff00' : ''">{{ (reward.probability * 100) | number:'1.0-0' }}%</div>
|
||||||
</div>
|
</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>
|
</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 3.7s forwards;">
|
<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)="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>
|
<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>
|
||||||
|
|
|
@ -94,8 +94,8 @@ export default class LootboxOpeningComponent {
|
||||||
generateCasePrizes(wonReward: Reward) {
|
generateCasePrizes(wonReward: Reward) {
|
||||||
if (!this.lootbox) return;
|
if (!this.lootbox) return;
|
||||||
|
|
||||||
// Create a case opening display with fewer prizes to fit on screen without scrolling
|
// Create a case opening display with an extremely large number of prizes for a massive scrolling animation
|
||||||
const prizeCount = 9; // Total number of prizes to show (odd number to have center prize)
|
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
|
||||||
|
@ -166,4 +166,14 @@ export default class LootboxOpeningComponent {
|
||||||
reward.value === this.wonReward.value &&
|
reward.value === this.wonReward.value &&
|
||||||
reward.probability === this.wonReward.probability;
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
Reference in a new issue