| | <!DOCTYPE html> |
| | <html> |
| | <head> |
| | <title>Colorful Lucky Roulette</title> |
| | <style> |
| | body { |
| | background: #1c1c1c; |
| | display: flex; |
| | justify-content: center; |
| | align-items: center; |
| | min-height: 100vh; |
| | margin: 0; |
| | font-family: 'Arial', sans-serif; |
| | } |
| | |
| | #roulette-container { |
| | position: relative; |
| | width: 500px; |
| | height: 500px; |
| | perspective: 1000px; |
| | } |
| | |
| | .roulette { |
| | width: 100%; |
| | height: 100%; |
| | border-radius: 50%; |
| | position: relative; |
| | border: 15px solid #ffd700; |
| | box-shadow: |
| | 0 0 30px rgba(255, 215, 0, 0.3), |
| | inset 0 0 50px rgba(0,0,0,0.5); |
| | transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99); |
| | background: conic-gradient( |
| | #ff6b6b, #4ecdc4, #45b7d1, #96c93d, |
| | #e056fd, #f7d794, #ff7675, #74b9ff, |
| | #a8e6cf, #fdcb6e, #4834d4, #6c5ce7 |
| | ); |
| | } |
| | |
| | .segment { |
| | position: absolute; |
| | width: 50%; |
| | height: 2px; |
| | top: 50%; |
| | left: 50%; |
| | transform-origin: left; |
| | background: rgba(255,255,255,0.8); |
| | box-shadow: 0 0 5px rgba(255,255,255,0.5); |
| | } |
| | |
| | .number { |
| | position: absolute; |
| | width: 45px; |
| | height: 45px; |
| | background: rgba(255,255,255,0.95); |
| | border-radius: 50%; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | font-weight: bold; |
| | font-size: 18px; |
| | transform-origin: center; |
| | border: 2px solid #ffd700; |
| | box-shadow: 0 0 10px rgba(0,0,0,0.3); |
| | color: #222; |
| | } |
| | |
| | .prize { |
| | position: absolute; |
| | color: #fff; |
| | transform-origin: center; |
| | font-size: 14px; |
| | font-weight: bold; |
| | text-shadow: 2px 2px 4px rgba(0,0,0,0.5); |
| | white-space: nowrap; |
| | background: rgba(0,0,0,0.4); |
| | padding: 3px 8px; |
| | border-radius: 15px; |
| | } |
| | |
| | .arrow { |
| | position: absolute; |
| | top: -40px; |
| | left: 50%; |
| | transform: translateX(-50%); |
| | width: 0; |
| | height: 0; |
| | border-left: 25px solid transparent; |
| | border-right: 25px solid transparent; |
| | border-top: 40px solid #ffd700; |
| | filter: drop-shadow(0 0 10px rgba(255,215,0,0.5)); |
| | } |
| | |
| | #shoot-btn { |
| | position: absolute; |
| | bottom: -80px; |
| | left: 50%; |
| | transform: translateX(-50%); |
| | padding: 15px 40px; |
| | font-size: 22px; |
| | background: linear-gradient(45deg, #ffd700, #ffeb3b); |
| | color: #222; |
| | border: none; |
| | border-radius: 25px; |
| | cursor: pointer; |
| | transition: all 0.3s; |
| | font-weight: bold; |
| | box-shadow: 0 5px 15px rgba(255,215,0,0.3); |
| | } |
| | |
| | #shoot-btn:hover { |
| | transform: translateX(-50%) scale(1.05); |
| | box-shadow: 0 7px 20px rgba(255,215,0,0.4); |
| | } |
| | |
| | #result { |
| | position: absolute; |
| | top: -80px; |
| | left: 0; |
| | width: 100%; |
| | text-align: center; |
| | color: #ffd700; |
| | font-size: 28px; |
| | font-weight: bold; |
| | opacity: 0; |
| | transition: opacity 0.3s; |
| | text-shadow: 0 0 10px rgba(255,215,0,0.5); |
| | } |
| | |
| | #result.show { |
| | opacity: 1; |
| | } |
| | |
| | .center-dot { |
| | position: absolute; |
| | top: 50%; |
| | left: 50%; |
| | width: 30px; |
| | height: 30px; |
| | background: #ffd700; |
| | border-radius: 50%; |
| | transform: translate(-50%, -50%); |
| | box-shadow: 0 0 20px rgba(255,215,0,0.5); |
| | } |
| | |
| | .glow { |
| | position: absolute; |
| | top: -10px; |
| | left: -10px; |
| | right: -10px; |
| | bottom: -10px; |
| | border-radius: 50%; |
| | background: transparent; |
| | border: 2px solid rgba(255,215,0,0.3); |
| | animation: glowPulse 2s infinite; |
| | } |
| | |
| | @keyframes glowPulse { |
| | 0% { transform: scale(1); opacity: 0.5; } |
| | 50% { transform: scale(1.05); opacity: 0.8; } |
| | 100% { transform: scale(1); opacity: 0.5; } |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div id="roulette-container"> |
| | <div id="result"></div> |
| | <div class="arrow"></div> |
| | <div class="roulette"> |
| | <div class="glow"></div> |
| | <div class="center-dot"></div> |
| | </div> |
| | <button id="shoot-btn">SHOOT! π―</button> |
| | </div> |
| |
|
| | <script> |
| | const roulette = document.querySelector('.roulette'); |
| | const shootBtn = document.getElementById('shoot-btn'); |
| | const result = document.getElementById('result'); |
| | |
| | const numSegments = 12; |
| | const prizes = [ |
| | 'κ½ π', '1λ§μ π«', '3λ§μ β¨', '5λ§μ π', |
| | '10λ§μ π', '20λ§μ π―', '30λ§μ π¨', |
| | '40λ§μ π', '50λ§μ β', '70λ§μ π', |
| | '90λ§μ π', '100λ§μ π' |
| | ]; |
| | let shuffledPrizes = [...prizes]; |
| | |
| | function shufflePrizes() { |
| | shuffledPrizes = [...prizes]; |
| | for (let i = shuffledPrizes.length - 1; i > 0; i--) { |
| | const j = Math.floor(Math.random() * (i + 1)); |
| | [shuffledPrizes[i], shuffledPrizes[j]] = [shuffledPrizes[j], shuffledPrizes[i]]; |
| | } |
| | } |
| | |
| | function createRouletteSegments() { |
| | const radius = 220; |
| | const angleIncrement = (2 * Math.PI) / numSegments; |
| | |
| | for (let i = 0; i < numSegments; i++) { |
| | const segment = document.createElement('div'); |
| | segment.className = 'segment'; |
| | segment.style.transform = `rotate(${i * (360 / numSegments)}deg)`; |
| | roulette.appendChild(segment); |
| | |
| | const number = document.createElement('div'); |
| | number.className = 'number'; |
| | number.textContent = i + 1; |
| | const angle = i * angleIncrement; |
| | const x = Math.cos(angle) * radius + 230; |
| | const y = Math.sin(angle) * radius + 230; |
| | number.style.left = `${x}px`; |
| | number.style.top = `${y}px`; |
| | roulette.appendChild(number); |
| | |
| | const prize = document.createElement('div'); |
| | prize.className = 'prize'; |
| | prize.textContent = shuffledPrizes[i]; |
| | const prizeRadius = radius - 60; |
| | const prizeX = Math.cos(angle) * prizeRadius + 230; |
| | const prizeY = Math.sin(angle) * prizeRadius + 230; |
| | prize.style.left = `${prizeX}px`; |
| | prize.style.top = `${prizeY}px`; |
| | prize.style.transform = `translate(-50%, -50%) rotate(${i * (360 / numSegments)}deg)`; |
| | roulette.appendChild(prize); |
| | } |
| | } |
| | |
| | let isSpinning = false; |
| | let currentRotation = 0; |
| | |
| | shufflePrizes(); |
| | createRouletteSegments(); |
| | |
| | shootBtn.addEventListener('click', () => { |
| | if (isSpinning) return; |
| | |
| | isSpinning = true; |
| | result.classList.remove('show'); |
| | shootBtn.style.opacity = '0.5'; |
| | shootBtn.style.cursor = 'not-allowed'; |
| | |
| | const randomSegment = Math.floor(Math.random() * numSegments); |
| | const segmentAngle = (360 / numSegments) * randomSegment; |
| | const extraSpins = 720 + Math.random() * 720; |
| | const totalRotation = extraSpins + segmentAngle; |
| | |
| | currentRotation += totalRotation; |
| | roulette.style.transform = `rotate(${currentRotation}deg)`; |
| | |
| | setTimeout(() => { |
| | isSpinning = false; |
| | result.textContent = `π ${randomSegment + 1}λ²: ${shuffledPrizes[randomSegment]} π`; |
| | result.classList.add('show'); |
| | shootBtn.style.opacity = '1'; |
| | shootBtn.style.cursor = 'pointer'; |
| | }, 4000); |
| | }); |
| | |
| | let baseRotation = 0; |
| | function animate() { |
| | if (!isSpinning) { |
| | baseRotation += 0.2; |
| | roulette.style.transform = `rotate(${baseRotation}deg)`; |
| | } |
| | requestAnimationFrame(animate); |
| | } |
| | animate(); |
| | </script> |
| | </body> |
| | </html> |