UNPKG

@phucbm/magnetic-button

Version:

A lightweight TypeScript library that creates smooth magnetic attraction effects for HTML elements

8 lines (7 loc) 2.35 kB
/*! * @phucbm/magnetic-button v0.0.3 * A lightweight TypeScript library that creates smooth magnetic attraction effects for HTML elements * @license MIT */ var f=Object.defineProperty;var p=(s,t,e)=>t in s?f(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var c=(s,t,e)=>p(s,typeof t!="symbol"?t+"":t,e);import l from"@phucbm/lerp";var a=class a{constructor(t,e={}){c(this,"settings",{activeClass:"magnetizing",attraction:.3,distance:200,fraction:.1,onEnter:()=>{},onExit:()=>{},onUpdate:()=>{}});c(this,"isEnter",!1);c(this,"lerpPos",{x:0,y:0});if(!t){document.querySelectorAll("[data-magnetic]").forEach(n=>{a.initializedElements.has(n)||new a(n,e)});return}if(a.initializedElements.has(t))return;a.initializedElements.add(t);let i=parseFloat(t.getAttribute("data-distance")||""),o=parseFloat(t.getAttribute("data-attraction")||""),r=parseFloat(t.getAttribute("data-fraction")||"");this.settings={...this.settings,attraction:isNaN(o)?e.attraction??this.settings.attraction:o,distance:isNaN(i)?e.distance??this.settings.distance:i,fraction:isNaN(r)?e.fraction??this.settings.fraction:r,...e},window.addEventListener("mousemove",n=>this.magnetize(t,n)),t.classList.add("is-magnetized")}magnetize(t,e){let i=this.calculateCoordinates(t,e.clientX,e.clientY);i.distance<this.settings.distance?(this.animateButton(t,i.deltaX,i.deltaY),this.isEnter||(this.isEnter=!0,t.classList.add(this.settings.activeClass),this.settings.onEnter(i)),this.settings.onUpdate(i)):(this.animateButton(t,0,0),this.isEnter&&(this.isEnter=!1,t.classList.remove(this.settings.activeClass),this.settings.onExit(i)))}animateButton(t,e,i){this.lerpPos.x=l(this.lerpPos.x,e,this.settings.fraction),this.lerpPos.y=l(this.lerpPos.y,i,this.settings.fraction),t.style.transform=`translate(${this.lerpPos.x}px, ${this.lerpPos.y}px)`}calculateCoordinates(t,e,i){let o=t.getBoundingClientRect(),r=o.left+t.offsetWidth/2,n=o.top+t.offsetHeight/2,u=(e-r)*this.settings.attraction,h=(i-n)*this.settings.attraction,m=Math.sqrt(Math.pow(e-r,2)+Math.pow(i-n,2));return{deltaX:u,deltaY:h,distance:m}}};c(a,"initializedElements",new WeakSet);var d=a;typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>new d):new d);var v=d;export{d as MagneticButton,v as default}; //# sourceMappingURL=index.min.js.map