luminomorphism
Version:
A UI design system built around light, blur, ambient motion and perceptual feedback.
2 lines (1 loc) • 2.61 kB
JavaScript
class LCursorThread extends HTMLElement{constructor(){super(),this.target=null,this.canvas=null,this.ctx=null,this.mouse={x:0,y:0},this.mode="solid",this.particleProgress=0}static get observedAttributes(){return["mode"]}attributeChangedCallback(t,s,i){t==="mode"&&(this.mode=i||"solid",console.log("Thread mode changed to:",this.mode))}connectedCallback(){this.mode=this.getAttribute("mode")||"solid",this.render(),this.observeTargets(),window.addEventListener("mousemove",this.updateMouse.bind(this)),requestAnimationFrame(this.animate.bind(this))}disconnectedCallback(){window.removeEventListener("mousemove",this.updateMouse),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}render(){this.canvas=document.createElement("canvas"),this.canvas.style.position="fixed",this.canvas.style.top=0,this.canvas.style.left=0,this.canvas.style.zIndex=9999,this.canvas.style.pointerEvents="none",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight,this.ctx=this.canvas.getContext("2d"),document.body.appendChild(this.canvas),window.addEventListener("resize",()=>{this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight})}observeTargets(){setTimeout(()=>{[...document.querySelectorAll("button, input, textarea, [tabindex]")].forEach(s=>{s.addEventListener("mouseenter",()=>this.target=s),s.addEventListener("mouseleave",()=>this.target=null)})},0)}updateMouse(t){this.mouse.x=t.clientX,this.mouse.y=t.clientY}animate(){if(requestAnimationFrame(this.animate.bind(this)),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),!this.target)return;const t=this.target.getBoundingClientRect(),s=t.left+t.width/2,i=t.top+t.height/2,e=this.ctx;switch(e.beginPath(),e.moveTo(this.mouse.x,this.mouse.y),e.lineTo(s,i),e.lineWidth=2,this.mode){case"solid":e.setLineDash([]),e.strokeStyle="#00ffff",e.shadowBlur=0;break;case"glow":e.setLineDash([]),e.strokeStyle="#00ffff",e.shadowColor="#00ffff",e.shadowBlur=15;break;case"wave":e.strokeStyle="#00ffff",e.lineWidth=2,e.setLineDash([10,6]),e.lineDashOffset=performance.now()/20;break;case"laser":e.strokeStyle="#ff00ff",e.shadowColor="#ff00ff",e.shadowBlur=20,e.setLineDash([2,4]),e.lineDashOffset=-performance.now()/5;break;case"aura":e.strokeStyle="#00ffff",e.shadowColor="#00ffff",e.shadowBlur=25+Math.sin(performance.now()/300)*10,e.setLineDash([]);break;case"particles":e.strokeStyle="#00ffff",e.setLineDash([1,16]),e.lineDashOffset=-(performance.now()/3);break;default:e.strokeStyle="#00ffff",e.setLineDash([]),e.shadowBlur=0;break}e.stroke()}}customElements.define("l-cursor-thread",LCursorThread);