Create a cinematic loot-box sliding module for an online gaming platform called Nioplay.
34df658 verified | class LootBox extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| position: relative; | |
| width: 140px; | |
| height: 140px; | |
| perspective: 1000px; | |
| } | |
| .box-container { | |
| width: 100%; | |
| height: 100%; | |
| position: relative; | |
| transform-style: preserve-3d; | |
| transition: transform 0.5s ease; | |
| } | |
| .box-face { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| background: var(--box-color, #1E1E1E); | |
| border: 1px solid var(--glow-color, #FF8C00); | |
| border-radius: 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| box-shadow: 0 0 15px var(--glow-color, #FF8C00); | |
| } | |
| .box-front { | |
| transform: translateZ(20px); | |
| } | |
| .box-back { | |
| transform: rotateY(180deg) translateZ(20px); | |
| } | |
| .box-right { | |
| transform: rotateY(90deg) translateZ(70px); | |
| width: 40px; | |
| } | |
| .box-left { | |
| transform: rotateY(-90deg) translateZ(70px); | |
| width: 40px; | |
| } | |
| .box-top { | |
| transform: rotateX(90deg) translateZ(70px); | |
| height: 40px; | |
| background: linear-gradient(to bottom, var(--glow-color, #FF8C00), transparent); | |
| } | |
| .box-bottom { | |
| transform: rotateX(-90deg) translateZ(70px); | |
| height: 40px; | |
| } | |
| .box-lid { | |
| position: absolute; | |
| top: -40px; | |
| left: 0; | |
| width: 100%; | |
| height: 40px; | |
| background: var(--box-color, #1E1E1E); | |
| border: 1px solid var(--glow-color, #FF8C00); | |
| border-radius: 8px 8px 0 0; | |
| transform-origin: bottom center; | |
| transition: transform 0.5s ease; | |
| } | |
| .box-content { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: radial-gradient(circle, var(--glow-color, #FF8C00), transparent 70%); | |
| opacity: 0; | |
| transition: opacity 0.3s ease; | |
| border-radius: 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-weight: bold; | |
| } | |
| :host([open]) .box-lid { | |
| transform: rotateX(-120deg) translateY(-20px); | |
| } | |
| :host([open]) .box-content { | |
| opacity: 0.7; | |
| } | |
| </style> | |
| <div class="box-container"> | |
| <div class="box-face box-front"></div> | |
| <div class="box-face box-back"></div> | |
| <div class="box-face box-right"></div> | |
| <div class="box-face box-left"></div> | |
| <div class="box-face box-top"></div> | |
| <div class="box-face box-bottom"></div> | |
| <div class="box-lid"></div> | |
| <div class="box-content"> | |
| <slot name="content"></slot> | |
| </div> | |
| </div> | |
| `; | |
| this.setRarityStyle(); | |
| } | |
| static get observedAttributes() { | |
| return ['rarity']; | |
| } | |
| attributeChangedCallback(name, oldValue, newValue) { | |
| if (name === 'rarity') { | |
| this.setRarityStyle(); | |
| } | |
| } | |
| setRarityStyle() { | |
| const rarity = this.getAttribute('rarity') || 'common'; | |
| let color, glow; | |
| switch(rarity) { | |
| case 'rare': | |
| color = '#00AAFF'; | |
| break; | |
| case 'epic': | |
| color = '#AA00FF'; | |
| break; | |
| case 'legendary': | |
| color = '#FF8C00'; | |
| break; | |
| default: // common | |
| color = '#00FFAA'; | |
| } | |
| this.shadowRoot.host.style.setProperty('--glow-color', color); | |
| this.shadowRoot.querySelector('.box-front').innerHTML = `<i data-feather="box" stroke="${color}"></i>`; | |
| feather.replace(); | |
| } | |
| open() { | |
| this.setAttribute('open', ''); | |
| } | |
| close() { | |
| this.removeAttribute('open'); | |
| } | |
| } | |
| customElements.define('loot-box', LootBox); |