Create a premium, cinematic “Double Spin Loot Box Module” for an online sweepstakes casino platform called Nioplay. This should be a single, complete hero-style UI scene rendered in a WIDESCREEN 16:9 ASPECT RATIO. The image should not look like a webpage screenshot — instead, it should look like a high-end product UI render designed for presentation and implementation.
60c16c9
verified
| class MultiplierTrack extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this.multipliers = [ | |
| { value: 1 }, | |
| { value: 1.25 }, | |
| { value: 1.5 }, | |
| { value: 2 }, | |
| { value: 3 }, | |
| { value: 5 }, | |
| { value: 1 }, | |
| { value: 1.25 }, | |
| { value: 1.5 }, | |
| { value: 2 }, | |
| { value: 3 }, | |
| { value: 5 } | |
| ]; | |
| this.selectedIndex = 0; | |
| } | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| } | |
| render() { | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| width: 100%; | |
| position: relative; | |
| height: 80px; | |
| } | |
| .track { | |
| position: relative; | |
| height: 60px; | |
| background: rgba(20, 20, 20, 0.5); | |
| border-radius: 30px; | |
| border: 1px solid rgba(255, 140, 0, 0.2); | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); | |
| overflow: hidden; | |
| } | |
| .multipliers-container { | |
| position: absolute; | |
| display: flex; | |
| height: 100%; | |
| align-items: center; | |
| gap: 15px; | |
| padding: 0 50%; | |
| will-change: transform; | |
| transition: transform 0.1s linear; | |
| } | |
| .multiplier { | |
| min-width: 80px; | |
| height: 40px; | |
| border-radius: 20px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| background: rgba(30, 30, 30, 0.8); | |
| border: 1px solid rgba(255, 215, 0, 0.3); | |
| color: rgba(255, 215, 0, 0.8); | |
| font-weight: bold; | |
| transition: all 0.3s ease; | |
| } | |
| .multiplier.selected { | |
| background: rgba(255, 140, 0, 0.3); | |
| border: 1px solid rgba(255, 215, 0, 0.8); | |
| color: white; | |
| box-shadow: 0 0 15px rgba(255, 140, 0, 0.5); | |
| transform: scale(1.1); | |
| } | |
| .selection-window { | |
| position: absolute; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| height: 50px; | |
| width: 90px; | |
| border: 2px solid rgba(255, 140, 0, 0.8); | |
| border-radius: 25px; | |
| box-shadow: 0 0 15px rgba(255, 140, 0, 0.5); | |
| z-index: 4; | |
| pointer-events: none; | |
| } | |
| </style> | |
| <div class="track"> | |
| <div class="selection-window"></div> | |
| <div class="multipliers-container"> | |
| ${this.multipliers.map((mult, index) => ` | |
| <div class="multiplier ${index === this.selectedIndex ? 'selected' : ''}" data-index="${index}"> | |
| ×${mult.value} | |
| </div> | |
| `).join('')} | |
| </div> | |
| </div> | |
| `; | |
| } | |
| startSpin() { | |
| const container = this.shadowRoot.querySelector('.multipliers-container'); | |
| const multipliers = this.shadowRoot.querySelectorAll('.multiplier'); | |
| // Reset selection | |
| multipliers.forEach(mult => mult.classList.remove('selected')); | |
| // Animate spin | |
| let currentPosition = 0; | |
| let speed = 0; | |
| const maxSpeed = 20; | |
| const deceleration = 0.3; | |
| const targetIndex = Math.floor(Math.random() * this.multipliers.length); | |
| const animate = () => { | |
| currentPosition += speed; | |
| speed = Math.max(0, speed - deceleration); | |
| // Apply movement | |
| container.style.transform = `translateX(${currentPosition}px)`; | |
| // Highlight multiplier in center | |
| const centerPosition = -currentPosition - container.offsetWidth / 2 + this.offsetWidth / 2; | |
| const multWidth = 95; // multiplier width + gap | |
| const centerIndex = Math.round(centerPosition / multWidth) % this.multipliers.length; | |
| const selectedIndex = (centerIndex + this.multipliers.length) % this.multipliers.length; | |
| multipliers.forEach((mult, i) => { | |
| mult.classList.toggle('selected', i === selectedIndex); | |
| }); | |
| // Continue animation until stopped | |
| if (speed > 0) { | |
| requestAnimationFrame(animate); | |
| } else { | |
| // Final selection | |
| this.selectedIndex = targetIndex; | |
| this.render(); | |
| } | |
| }; | |
| // Initial acceleration | |
| speed = maxSpeed; | |
| animate(); | |
| } | |
| getSelectedMultiplier() { | |
| return this.multipliers[this.selectedIndex]; | |
| } | |
| } | |
| customElements.define('multiplier-track', MultiplierTrack); |