ProjectGenesis's picture
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);