Download roolet.html from openfree/testhtml: direct link, hf CLI and curl.
- Browser
- Download file 8.77 kB
-
https://huggingface.co/spaces/openfree/testhtml/resolve/main/roolet.html
- Command line
-
hf download hf://spaces/openfree/testhtml/roolet.html
-
curl -L -o roolet.html https://huggingface.co/spaces/openfree/testhtml/resolve/main/roolet.html
8.77 kB
| <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> |