| class NumberDisplay extends HTMLElement { | |
| constructor() { | |
| super(); | |
| } | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.render(); | |
| } | |
| render() { | |
| const number = this.getAttribute('number') || '1'; | |
| const animation = this.getAttribute('animation') || 'zoom'; | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| .cinematic-number { | |
| position: relative; | |
| font-size: 30vw; | |
| font-weight: 900; | |
| color: transparent; | |
| background: linear-gradient(145deg, #8B0000, #B22222, #DC143C); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| text-shadow: | |
| 0 0 30px rgba(220, 20, 60, 0.8), | |
| 0 0 60px rgba(220, 20, 60, 0.6), | |
| 0 0 90px rgba(220, 20, 60, 0.4), | |
| 4px 4px 0px #000, | |
| 8px 8px 15px rgba(0, 0, 0, 0.8); | |
| transform-style: preserve-3d; | |
| perspective: 1000px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| height: 100%; | |
| } | |
| </style> | |
| <div class="cinematic-number" data-number="${number}"> | |
| ${number} | |
| </div> | |
| `; | |
| } | |
| static get observedAttributes() { | |
| return ['number', 'animation']; | |
| } | |
| attributeChangedCallback(name, oldValue, newValue) { | |
| if (oldValue !== newValue) { | |
| this.render(); | |
| } | |
| } | |
| } | |
| customElements.define('number-display', NumberDisplay); |