class CinematicNumber extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
static get observedAttributes() {
return ['number', 'animation', 'loop'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this.render();
}
}
render() {
const number = this.getAttribute('number') || '1';
const animation = this.getAttribute('animation') || 'zoom';
const loop = this.getAttribute('loop') === 'true';
this.shadowRoot.innerHTML = `
`;
this.applyAnimation(animation);
}
applyAnimation(animationType) {
const numberElement = this.shadowRoot.querySelector('.cinematic-number');
const particlesContainer = this.shadowRoot.querySelector('.particles');
// Remove existing particles
particlesContainer.innerHTML = '';
switch(animationType) {
case 'smoke':
this.createParticles(particlesContainer);
break;
}
}
createParticles(container) {
for (let i = 0; i < 20; i++) {
const particle = document.createElement('div');
particle.classList.add('particle');
const angle = Math.random() * Math.PI * 2;
const distance = 80 + Math.random() * 120;
const tx = Math.cos(angle) * distance;
const ty = Math.sin(angle) * distance;
particle.style.setProperty('--tx', `${tx}px`);
particle.style.setProperty('--ty', `${ty}px`);
particle.style.left = '50%';
particle.style.top = '50%';
particle.style.animationDelay = `${Math.random() * 0.3}s`;
container.appendChild(particle);
}
}
}
customElements.define('cinematic-number', CinematicNumber);