ProjectGenesis commited on
Commit
0dfe679
Β·
verified Β·
1 Parent(s): 550b2d4

<!DOCTYPE html>

Browse files

<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Nioplay Loot Box + Multiplier Demo</title>
<style>
:root {
--bg: #050505;
--accent: #ff8c00;
--accent-soft: rgba(255, 140, 0, 0.3);
--gold: #ffcc66;
--text-main: #f7f7f7;
--text-dim: #a7a7a7;
--loot-box-size: 90px;
--pill-width: 90px;
--pill-height: 40px;
--gap: 18px;
--transition-duration: 1100ms;
}

* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: radial-gradient(circle at top, #1a0d00 0%, #000 55%);
font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text",
"Segoe UI", sans-serif;
color: var(--text-main);
}

.module {
width: 1100px;
max-width: 100%;
border-radius: 24px;
padding: 28px 32px 36px;
background:
radial-gradient(circle at top, rgba(255, 140, 0, 0.16), transparent 65%),
linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(10, 10, 10, 0.95));
box-shadow:
0 0 40px rgba(0, 0, 0, 0.9),
0 0 60px rgba(255, 140, 0, 0.35);
border: 1px solid rgba(255, 255, 255, 0.08);
backdrop-filter: blur(18px);
}

.label {
font-size: 12px;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--text-dim);
margin-bottom: 6px;
}

.section {
margin-bottom: 24px;
}

.track-shell {
position: relative;
padding: 22px 0;
border-radius: 18px;
background:
radial-gradient(circle at top, rgba(255, 140, 0, 0.18), transparent 60%),
linear-gradient(to bottom, rgba(10, 10, 10, 0.98), rgba(5, 5, 5, 0.98));
box-shadow:
0 12px 30px rgba(0, 0, 0, 0.85),
inset 0 0 0 1px rgba(255, 255, 255, 0.04);
overflow: hidden;
}

.track-wrapper {
overflow: hidden;
padding: 0 70px;
}

.track {
display: flex;
align-items: center;
gap: var(--gap);
transform: translateX(0px);
will-change: transform;
}

.selection-window {
position: absolute;
top: 16px;
left: 50%;
transform: translateX(-50%);
border-radius: 16px;
border: 2px solid var(--accent);
box-shadow:
0 0 18px rgba(255, 140, 0, 0.9),
0 0 40px rgba(255, 140, 0, 0.4);
pointer-events: none;
z-index: 4;
}

.selection-window--loot {
width: var(--loot-box-size);
height: var(--loot-box-size) + 20px;
}

.selection-window--multi {
width: var(--pill-width);
height: var(--pill-height) + 12px;
}

.selection-window::before {
content: "";
position: absolute;
inset: -16px;
border-radius: inherit;
background: radial-gradient(
circle at center,
rgba(255, 140, 0, 0.14),
transparent 60%
);
opacity: 0.8;
}

/* Loot boxes */

.loot-box {
width: var(--loot-box-size);
height: var(--loot-box-size);
border-radius: 18px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.08);
background: radial-gradient(circle at top, #171717, #050505);
box-shadow:
0 8px 18px rgba(0, 0, 0, 0.85),
0 0 18px rgba(0, 0, 0, 0.7);
overflow: hidden;
transition:
transform 160ms ease-out,
box-shadow 160ms ease-out,
border-color 160ms ease-out,
filter 160ms ease-out;
}

.loot-box::before {
content: "";
position: absolute;
inset: 8px;
border-radius: 14px;
border: 2px solid rgba(255, 255, 255, 0.16);
box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.9);
z-index: 1;
}

.loot-box-inner {
position: relative;
z-index: 2;
width: 48px;
height: 48px;
border-radius: 14px;
background: radial-gradient(circle at top, #222, #000);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 0 14px rgba(0, 0, 0, 0.8);
}

.loot-box-inner::before {
content: "";
width: 22px;
height: 22px;
border-radius: 6px;
border: 2px solid rgba(255, 255, 255, 0.6);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.3);
}

.loot-box[data-rarity="green"] {
box-shadow: 0 0 18px rgba(0, 200, 120, 0.7);
}

.loot-box[data-rarity="blue"] {
box-shadow: 0 0 18px rgba(80, 160, 255, 0.8);
}

.loot-box[data-rarity="purple"] {
box-shadow: 0 0 20px rgba(160, 80, 255, 0.85);
}

.loot-box[data-rarity="gold"] {
box-shadow: 0 0 22px rgba(255, 190, 70, 0.95);
}

.loot-box.selected {
transform: scale(1.12);
border-color: rgba(255, 140, 0, 0.95);
filter: brightness(1.1);
box-shadow:
0 0 26px rgba(255, 140, 0, 0.95),
0 0 60px rgba(255, 140, 0, 0.75);
}

.loot-box.motion-blur {
filter: blur(1px) brightness(0.9);
opacity: 0.9;
}

/* Multiplier pills */

.multi-pill {
min-width: var(--pill-width);
height: var(--pill-height);
border-radius: 999px;
display: flex;
align-items: center;
justify-content: center;
font-size: 17px;
font-weight: 700;
color: #ffd8a0;
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(6px);
box-shadow:
0 0 8px rgba(0, 0, 0, 0.6),
inset 0 0 6px rgba(255, 255, 255, 0.1);
transition:
transform 140ms ease-out,
color 140ms ease-out,
box-shadow 140ms ease-out,
filter 140ms ease-out;
}

.multi-pill.selected {
transform: scale(1.18);
color: #fff2cc;
box-shadow:
0 0 20px rgba(255, 140, 0, 0.95),
0 0 50px rgba(255, 140, 0, 0.6);
}

.multi-pill.motion-blur {
filter: blur(1px) brightness(0.95);
opacity: 0.9;
}

/* Spin button */

.actions {
display: flex;
justify-content: center;
margin-top: 10px;
}

.spin-btn {
min-width: 220px;
border: none;
border-radius: 999px;
padding: 12px 32px;
font-size: 14px;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
cursor: pointer;
background: radial-gradient(circle at top, #ffe5a8, #ff8c00);
color: #1a0900;
box-shadow:
0 0 30px rgba(255, 140, 0, 0.95),
0 14px 26px rgba(0, 0, 0, 0.9);
position: relative;
overflow: hidden;
transition:
transform 120ms ease-out,
box-shadow 120ms ease-out,
filter 120ms ease-out;
}

.spin-btn::before {
content: "";
position: absolute;
inset: 0;
background: radial-gradient(circle at 20% 0%, rgba(255, 255, 255, 0.35), transparent 60%);
opacity: 0.8;
pointer-events: none;
mix-blend-mode: screen;
}

.spin-btn:active {
transform: translateY(1px) scale(0.98);
box-shadow:
0 0 18px rgba(255, 140, 0, 0.8),
0 6px 10px rgba(0, 0, 0, 0.9);
filter: brightness(0.96);
}

.spin-btn.disabled {
cursor: wait;
filter: grayscale(0.1) brightness(0.9);
box-shadow:
0 0 14px rgba(255, 140, 0, 0.6),
0 8px 18px rgba(0, 0, 0, 0.9);
}

/* Popup */

.popup-backdrop {
position: fixed;
inset: 0;
display: none;
align-items: center;
justify-content: center;
background: radial-gradient(circle at center, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0.95));
z-index: 50;
}

.popup-backdrop.visible {
display: flex;
}

.popup {
width: 360px;
max-width: 90%;
padding: 22px 22px 20px;
border-radius: 20px;
background:
radial-gradient(circle at top, rgba(255, 140, 0, 0.22), transparent 60%),
linear-gradient(135deg, rgba(25, 25, 25, 0.98), rgba(5, 5, 5, 0.98));
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow:
0 0 40px rgba(0, 0, 0, 1),
0 0 50px rgba(255, 140, 0, 0.85);
text-align: center;
position: relative;
overflow: hidden;
}

.popup::before {
content: "";
position: absolute;
inset: -40%;
background: radial-gradient(circle at center, rgba(255, 140, 0, 0.25), transparent 70%);
opacity: 0.7;
pointer-events: none;
}

.popup-title {
position: relative;
z-index: 1;
font-size: 14px;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(--text-dim);
margin-bottom: 8px;
}

.popup-total {
position: relative;
z-index: 1;
font-size: 30px;
font-weight: 800;
color: var(--gold);
text-shadow:
0 0 18px rgba(255, 204, 102, 0.9),
0 0 40px rgba(255, 140, 0, 0.85);
margin-bottom: 6px;
}

.popup-line {
position: relative;
z-index: 1;
font-size: 13px;
color: var(--text-dim);
margin-bottom: 3px;
}

.popup-close {
position: relative;
z-index: 1;
margin-top: 12px;
border: none;
border-radius: 999px;
padding: 8px 20px;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.16em;
text-transform: uppercase;
cursor: pointer;
background: radial-gradient(circle at top, #ffe0a0, #ff8c00);
color: #1a0900;
box-shadow:
0 0 20px rgba(255, 140, 0, 0.9),
0 8px 16px rgba(0, 0, 0, 0.9);
}



@media
(max-width: 900px) {
.module {
padding: 20px 16px 24px;
}
.track-wrapper {
padding: 0 40px;
}
}
</style>
</head>
<body>
<div class="module">
<!-- Loot box carousel -->
<div class="section">
<div class="label">LOOT BOX SPIN</div>
<div class="track-shell">
<div class="selection-window selection-window--loot"></div>
<div class="track-wrapper" id="lootWrapper">
<div cl

Files changed (5) hide show
  1. README.md +8 -5
  2. components/loot-box.js +9 -0
  3. index.html +111 -19
  4. script.js +198 -0
  5. style.css +88 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Lootbox Bonanza Spinner
3
- emoji: 🌍
4
- colorFrom: pink
5
- colorTo: pink
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: LootBox Bonanza Spinner 🎰
3
+ colorFrom: purple
4
+ colorTo: gray
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/loot-box.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ class LootBox extends HTMLElement {
2
+ constructor() {
3
+ super();
4
+ this.attachShadow({ mode: 'open' });
5
+ }
6
+
7
+ connectedCallback() {
8
+ const type = this.getAttribute('type') || 'common';
9
+ const value = this.get
index.html CHANGED
@@ -1,19 +1,111 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>LootBox Bonanza Spinner</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <link rel="stylesheet" href="style.css">
11
+ </head>
12
+ <body class="bg-gray-900 min-h-screen flex items-center justify-center p-6">
13
+ <div class="max-w-4xl w-full rounded-3xl p-8 bg-gradient-to-br from-gray-800 to-gray-900 border border-gray-700 shadow-2xl">
14
+ <!-- Header -->
15
+ <div class="flex justify-between items-center mb-8">
16
+ <h1 class="text-3xl font-bold text-orange-400 flex items-center">
17
+ <i data-feather="gift" class="mr-2"></i> LootBox Bonanza
18
+ </h1>
19
+ <div class="flex items-center space-x-4">
20
+ <div class="bg-gray-700 px-4 py-2 rounded-full flex items-center">
21
+ <i data-feather="star" class="text-yellow-400 mr-2"></i>
22
+ <span class="font-bold text-white">5,000</span>
23
+ </div>
24
+ <button class="bg-orange-500 hover:bg-orange-600 text-white px-4 py-2 rounded-full transition-all">
25
+ <i data-feather="plus" class="mr-1"></i> Add Funds
26
+ </button>
27
+ </div>
28
+ </div>
29
+
30
+ <!-- Main Game Area -->
31
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
32
+ <!-- Loot Box Section -->
33
+ <div class="bg-gray-800 rounded-2xl p-6 border border-gray-700 shadow-lg">
34
+ <h2 class="text-xl font-semibold text-white mb-4 flex items-center">
35
+ <i data-feather="box" class="mr-2 text-orange-400"></i> Loot Boxes
36
+ </h2>
37
+ <div class="relative h-40 overflow-hidden">
38
+ <div class="absolute inset-0 flex items-center">
39
+ <div class="w-full h-32 bg-gray-900 rounded-xl border-2 border-orange-500 shadow-[0_0_20px_rgba(255,140,0,0.5)]"></div>
40
+ </div>
41
+ <div id="lootBoxTrack" class="absolute inset-0 flex items-center space-x-6 px-4">
42
+ <!-- Loot boxes will be added here by JavaScript -->
43
+ </div>
44
+ </div>
45
+ <div class="mt-6 flex justify-center">
46
+ <button id="spinLootBtn" class="bg-gradient-to-r from-orange-500 to-yellow-500 hover:from-orange-600 hover:to-yellow-600 text-white font-bold py-3 px-8 rounded-full shadow-lg transition-all transform hover:scale-105">
47
+ Spin Loot Box (10 coins)
48
+ </button>
49
+ </div>
50
+ </div>
51
+
52
+ <!-- Multiplier Section -->
53
+ <div class="bg-gray-800 rounded-2xl p-6 border border-gray-700 shadow-lg">
54
+ <h2 class="text-xl font-semibold text-white mb-4 flex items-center">
55
+ <i data-feather="zap" class="mr-2 text-yellow-400"></i> Multiplier
56
+ </h2>
57
+ <div class="relative h-24 overflow-hidden">
58
+ <div class="absolute inset-0 flex items-center">
59
+ <div class="w-full h-16 bg-gray-900 rounded-xl border-2 border-yellow-500 shadow-[0_0_20px_rgba(255,215,0,0.3)]"></div>
60
+ </div>
61
+ <div id="multiplierTrack" class="absolute inset-0 flex items-center space-x-4 px-4">
62
+ <!-- Multipliers will be added here by JavaScript -->
63
+ </div>
64
+ </div>
65
+ <div class="mt-6 flex justify-center">
66
+ <button id="spinMultiplierBtn" class="bg-gradient-to-r from-yellow-500 to-orange-500 hover:from-yellow-600 hover:to-orange-600 text-white font-bold py-3 px-8 rounded-full shadow-lg transition-all transform hover:scale-105">
67
+ Spin Multiplier (5 coins)
68
+ </button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ <!-- Result Display -->
74
+ <div class="mt-8 bg-gray-800 rounded-2xl p-6 border border-gray-700 shadow-lg">
75
+ <h2 class="text-xl font-semibold text-white mb-4 flex items-center">
76
+ <i data-feather="award" class="mr-2 text-yellow-400"></i> Your Prize
77
+ </h2>
78
+ <div class="flex flex-col items-center">
79
+ <div id="prizeDisplay" class="text-5xl font-bold text-yellow-400 mb-2">0</div>
80
+ <div class="text-gray-300 mb-4">SC</div>
81
+ <div id="prizeDetails" class="text-gray-400 text-center">
82
+ Spin to win amazing prizes!
83
+ </div>
84
+ <button id="claimBtn" class="mt-4 bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-6 rounded-full shadow transition-all transform hover:scale-105 hidden">
85
+ Claim Prize
86
+ </button>
87
+ </div>
88
+ </div>
89
+ </div>
90
+
91
+ <!-- Modal -->
92
+ <div id="winModal" class="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center hidden z-50">
93
+ <div class="bg-gradient-to-br from-gray-800 to-gray-900 rounded-3xl p-8 max-w-md w-full border-2 border-yellow-500 shadow-[0_0_40px_rgba(255,215,0,0.5)]">
94
+ <div class="text-center">
95
+ <i data-feather="award" class="text-yellow-400 w-16 h-16 mx-auto mb-4"></i>
96
+ <h3 class="text-2xl font-bold text-white mb-2">Congratulations!</h3>
97
+ <p class="text-gray-300 mb-6">You won <span id="modalPrize" class="text-yellow-400 font-bold">0</span> SC!</p>
98
+ <button id="modalCloseBtn" class="bg-orange-500 hover:bg-orange-600 text-white font-bold py-2 px-6 rounded-full transition-all">
99
+ Awesome!
100
+ </button>
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <script src="script.js"></script>
106
+ <script>
107
+ feather.replace();
108
+ </script>
109
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
110
+ </body>
111
+ </html>
script.js ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ // Initialize game state
3
+ let coins = 5000;
4
+ let currentPrize = 0;
5
+ let lootBoxes = [];
6
+ let multipliers = [];
7
+
8
+ // DOM elements
9
+ const lootBoxTrack = document.getElementById('lootBoxTrack');
10
+ const multiplierTrack = document.getElementById('multiplierTrack');
11
+ const spinLootBtn = document.getElementById('spinLootBtn');
12
+ const spinMultiplierBtn = document.getElementById('spinMultiplierBtn');
13
+ const prizeDisplay = document.getElementById('prizeDisplay');
14
+ const prizeDetails = document.getElementById('prizeDetails');
15
+ const claimBtn = document.getElementById('claimBtn');
16
+ const winModal = document.getElementById('winModal');
17
+ const modalPrize = document.getElementById('modalPrize');
18
+ const modalCloseBtn = document.getElementById('modalCloseBtn');
19
+
20
+ // Initialize loot boxes
21
+ function initLootBoxes() {
22
+ const boxTypes = [
23
+ { type: 'common', value: 10, color: 'gray-500' },
24
+ { type: 'common', value: 15, color: 'gray-500' },
25
+ { type: 'common', value: 20, color: 'gray-500' },
26
+ { type: 'rare', value: 30, color: 'blue-500' },
27
+ { type: 'rare', value: 40, color: 'blue-500' },
28
+ { type: 'epic', value: 60, color: 'purple-500' },
29
+ { type: 'epic', value: 80, color: 'purple-500' },
30
+ { type: 'legendary', value: 120, color: 'yellow-500' },
31
+ { type: 'legendary', value: 150, color: 'yellow-500' },
32
+ { type: 'jackpot', value: 300, color: 'orange-500' }
33
+ ];
34
+
35
+ // Create enough boxes for smooth scrolling
36
+ for (let i = 0; i < 30; i++) {
37
+ const box = boxTypes[i % boxTypes.length];
38
+ lootBoxes.push(box);
39
+
40
+ const boxElement = document.createElement('div');
41
+ boxElement.className = `loot-box ${box.type} flex-shrink-0 mx-2`;
42
+ boxElement.innerHTML = `
43
+ <div class="text-${box.color} text-2xl mb-1">
44
+ ${box.type === 'common' ? 'πŸ“¦' :
45
+ box.type === 'rare' ? '🎁' :
46
+ box.type === 'epic' ? 'πŸ’Ž' :
47
+ box.type === 'legendary' ? 'πŸ†' : 'πŸ’°'}
48
+ </div>
49
+ <div class="text-white text-sm">${box.value} SC</div>
50
+ `;
51
+ lootBoxTrack.appendChild(boxElement);
52
+ }
53
+ }
54
+
55
+ // Initialize multipliers
56
+ function initMultipliers() {
57
+ const multiplierValues = [1, 1.25, 1.5, 2, 3, 5, 1, 1.25, 1.5, 2, 3, 5];
58
+
59
+ // Create enough multipliers for smooth scrolling
60
+ for (let i = 0; i < 24; i++) {
61
+ const value = multiplierValues[i % multiplierValues.length];
62
+ multipliers.push(value);
63
+
64
+ const chip = document.createElement('div');
65
+ chip.className = 'multiplier-chip flex-shrink-0 mx-1';
66
+ chip.textContent = `Γ—${value}`;
67
+ chip.dataset.value = value;
68
+ multiplierTrack.appendChild(chip);
69
+ }
70
+ }
71
+
72
+ // Spin animation
73
+ function spin(element, items, spinTime, callback) {
74
+ const startTime = Date.now();
75
+ const speed = 0.5; // pixels per millisecond
76
+
77
+ function animate() {
78
+ const elapsed = Date.now() - startTime;
79
+ const progress = Math.min(elapsed / spinTime, 1);
80
+
81
+ // Ease-out function
82
+ const easeProgress = 1 - Math.pow(1 - progress, 3);
83
+
84
+ // Calculate distance (more at start, less at end)
85
+ const distance = speed * spinTime * (1 - easeProgress * 0.9);
86
+
87
+ element.style.transform = `translateX(-${distance}px)`;
88
+
89
+ if (progress < 1) {
90
+ requestAnimationFrame(animate);
91
+ } else {
92
+ // Snap to nearest item
93
+ const itemWidth = items[0].offsetWidth + 8; // 8px for margin
94
+ const totalDistance = parseInt(element.style.transform.replace('translateX(-', '').replace('px)', ''));
95
+ const itemIndex = Math.round(totalDistance / itemWidth) % items.length;
96
+ const snapDistance = itemIndex * itemWidth;
97
+
98
+ element.style.transition = 'transform 0.5s ease-out';
99
+ element.style.transform = `translateX(-${snapDistance}px)`;
100
+
101
+ setTimeout(() => {
102
+ element.style.transition = '';
103
+ if (callback) callback(itemIndex);
104
+ }, 500);
105
+ }
106
+ }
107
+
108
+ animate();
109
+ }
110
+
111
+ // Spin loot box
112
+ spinLootBtn.addEventListener('click', function() {
113
+ if (coins < 10) {
114
+ alert('Not enough coins!');
115
+ return;
116
+ }
117
+
118
+ coins -= 10;
119
+ updateCoinDisplay();
120
+ spinLootBtn.disabled = true;
121
+
122
+ spin(lootBoxTrack, lootBoxTrack.children, 3000, function(index) {
123
+ const selectedBox = lootBoxes[index % lootBoxes.length];
124
+ currentPrize = selectedBox.value;
125
+
126
+ prizeDisplay.textContent = currentPrize;
127
+ prizeDetails.innerHTML = `
128
+ You got a <span class="text-${selectedBox.color} font-bold">${selectedBox.type}</span> loot box!
129
+ `;
130
+
131
+ spinLootBtn.disabled = false;
132
+ claimBtn.classList.remove('hidden');
133
+ });
134
+ });
135
+
136
+ // Spin multiplier
137
+ spinMultiplierBtn.addEventListener('click', function() {
138
+ if (coins < 5) {
139
+ alert('Not enough coins!');
140
+ return;
141
+ }
142
+
143
+ if (currentPrize === 0) {
144
+ alert('Spin a loot box first!');
145
+ return;
146
+ }
147
+
148
+ coins -= 5;
149
+ updateCoinDisplay();
150
+ spinMultiplierBtn.disabled = true;
151
+
152
+ spin(multiplierTrack, multiplierTrack.children, 2500, function(index) {
153
+ const selectedMultiplier = multipliers[index % multipliers.length];
154
+ const totalPrize = Math.round(currentPrize * selectedMultiplier);
155
+
156
+ prizeDisplay.textContent = totalPrize;
157
+ prizeDetails.innerHTML += `
158
+ <div class="mt-2">Multiplier: <span class="text-yellow-400 font-bold">Γ—${selectedMultiplier}</span></div>
159
+ `;
160
+
161
+ currentPrize = totalPrize;
162
+ spinMultiplierBtn.disabled = false;
163
+
164
+ // Show win modal for big prizes
165
+ if (totalPrize >= 100) {
166
+ modalPrize.textContent = totalPrize;
167
+ winModal.classList.remove('hidden');
168
+ prizeDisplay.classList.add('winner-animation');
169
+ }
170
+ });
171
+ });
172
+
173
+ // Claim prize
174
+ claimBtn.addEventListener('click', function() {
175
+ coins += currentPrize;
176
+ currentPrize = 0;
177
+ updateCoinDisplay();
178
+
179
+ prizeDisplay.textContent = '0';
180
+ prizeDetails.textContent = 'Spin to win amazing prizes!';
181
+ prizeDisplay.classList.remove('winner-animation');
182
+ claimBtn.classList.add('hidden');
183
+ });
184
+
185
+ // Close modal
186
+ modalCloseBtn.addEventListener('click', function() {
187
+ winModal.classList.add('hidden');
188
+ });
189
+
190
+ // Update coin display
191
+ function updateCoinDisplay() {
192
+ document.querySelector('.bg-gray-700 span').textContent = coins.toLocaleString();
193
+ }
194
+
195
+ // Initialize the game
196
+ initLootBoxes();
197
+ initMultipliers();
198
+ });
style.css CHANGED
@@ -1,28 +1,97 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
 
 
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @keyframes pulse {
2
+ 0%, 100% {
3
+ transform: scale(1);
4
+ }
5
+ 50% {
6
+ transform: scale(1.05);
7
+ }
8
  }
9
 
10
+ @keyframes float {
11
+ 0%, 100% {
12
+ transform: translateY(0);
13
+ }
14
+ 50% {
15
+ transform: translateY(-10px);
16
+ }
17
  }
18
 
19
+ .loot-box {
20
+ transition: all 0.3s ease;
21
+ min-width: 100px;
22
+ height: 120px;
23
+ background: linear-gradient(145deg, #2d3748, #1a202c);
24
+ border-radius: 12px;
25
+ display: flex;
26
+ flex-direction: column;
27
+ align-items: center;
28
+ justify-content: center;
29
+ border: 2px solid #4a5568;
30
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
31
  }
32
 
33
+ .loot-box:hover {
34
+ transform: translateY(-5px);
35
+ box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);
 
 
 
36
  }
37
 
38
+ .loot-box.common {
39
+ border-color: #718096;
40
  }
41
+
42
+ .loot-box.rare {
43
+ border-color: #4299e1;
44
+ box-shadow: 0 0 15px rgba(66, 153, 225, 0.5);
45
+ }
46
+
47
+ .loot-box.epic {
48
+ border-color: #9f7aea;
49
+ box-shadow: 0 0 20px rgba(159, 122, 234, 0.6);
50
+ }
51
+
52
+ .loot-box.legendary {
53
+ border-color: #f6ad55;
54
+ animation: pulse 2s infinite;
55
+ box-shadow: 0 0 25px rgba(246, 173, 85, 0.7);
56
+ }
57
+
58
+ .multiplier-chip {
59
+ min-width: 80px;
60
+ height: 50px;
61
+ background: linear-gradient(145deg, #2d3748, #1a202c);
62
+ border-radius: 25px;
63
+ display: flex;
64
+ align-items: center;
65
+ justify-content: center;
66
+ border: 2px solid #4a5568;
67
+ font-weight: bold;
68
+ transition: all 0.3s ease;
69
+ }
70
+
71
+ .multiplier-chip:hover {
72
+ transform: scale(1.05);
73
+ }
74
+
75
+ .multiplier-chip.active {
76
+ background: linear-gradient(145deg, #f6ad55, #f56565);
77
+ color: white;
78
+ border-color: #f6ad55;
79
+ box-shadow: 0 0 15px rgba(245, 101, 101, 0.5);
80
+ }
81
+
82
+ .spinning {
83
+ animation: spin 0.1s linear infinite;
84
+ }
85
+
86
+ @keyframes spin {
87
+ 0% {
88
+ transform: translateX(0);
89
+ }
90
+ 100% {
91
+ transform: translateX(-100%);
92
+ }
93
+ }
94
+
95
+ .winner-animation {
96
+ animation: float 2s ease-in-out infinite, pulse 1.5s ease-in-out infinite;
97
+ }