Spaces:
Running
Running
| class GlowingCursor extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| pointer-events: none; | |
| z-index: 9999; | |
| } | |
| .cursor { | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| background: radial-gradient(circle, #3B82F6, transparent); | |
| filter: blur(10px); | |
| transform: translate(-50%, -50%); | |
| pointer-events: none; | |
| transition: width 0.3s, height 0.3s; | |
| } | |
| .cursor-trail { | |
| position: absolute; | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| background: rgba(59, 130, 246, 0.3); | |
| filter: blur(5px); | |
| transform: translate(-50%, -50%); | |
| pointer-events: none; | |
| transition: opacity 0.3s; | |
| } | |
| </style> | |
| <div class="cursor"></div> | |
| `; | |
| this.initCursor(); | |
| } | |
| initCursor() { | |
| const cursor = this.shadowRoot.querySelector('.cursor'); | |
| const trails = []; | |
| document.addEventListener('mousemove', (e) => { | |
| // Update main cursor | |
| cursor.style.left = `${e.clientX}px`; | |
| cursor.style.top = `${e.clientY}px`; | |
| // Create trail | |
| const trail = document.createElement('div'); | |
| trail.className = 'cursor-trail'; | |
| trail.style.left = `${e.clientX}px`; | |
| trail.style.top = `${e.clientY}px`; | |
| this.shadowRoot.appendChild(trail); | |
| trails.push(trail); | |
| // Remove old trails | |
| if (trails.length > 10) { | |
| const oldTrail = trails.shift(); | |
| if (oldTrail.parentNode) { | |
| oldTrail.style.opacity = '0'; | |
| setTimeout(() => { | |
| if (oldTrail.parentNode) { | |
| this.shadowRoot.removeChild(oldTrail); | |
| } | |
| }, 300); | |
| } | |
| } | |
| // Remove trails after animation | |
| setTimeout(() => { | |
| if (trail.parentNode) { | |
| trail.style.opacity = '0'; | |
| setTimeout(() => { | |
| if (trail.parentNode) { | |
| this.shadowRoot.removeChild(trail); | |
| } | |
| }, 300); | |
| } | |
| }, 1000); | |
| }); | |
| // Hover effects | |
| document.addEventListener('mouseover', (e) => { | |
| if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { | |
| cursor.style.width = '40px'; | |
| cursor.style.height = '40px'; | |
| } | |
| }); | |
| document.addEventListener('mouseout', (e) => { | |
| if (e.target.tagName === 'A' || e.target.tagName === 'BUTTON') { | |
| cursor.style.width = '20px'; | |
| cursor.style.height = '20px'; | |
| } | |
| }); | |
| // Click effect | |
| document.addEventListener('click', () => { | |
| cursor.style.width = '30px'; | |
| cursor.style.height = '30px'; | |
| setTimeout(() => { | |
| cursor.style.width = '20px'; | |
| cursor.style.height = '20px'; | |
| }, 100); | |
| }); | |
| } | |
| } | |
| customElements.define('glowing-cursor', GlowingCursor); |