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