@yoannchb/cattract
Version:
Animate anything just like it was attracted by the cursor
3 lines (2 loc) • 3.98 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Cattract=e()}(this,(function(){"use strict";const t=[],e={elementRadius:20,detectionRadius:50,animation:{ease:"ease-in-out",duration:1e3}},i={maxAngle:35,perspective:500};return document.addEventListener("DOMContentLoaded",(function(){document.body.addEventListener("mousemove",(function(e){const[i,s]=[e.clientX,e.clientY];for(const e of t)e.target.isConnected?e.update(i,s):e.stop()}))})),class{constructor(t,s={}){var n;this.target=t,this.options=s,this.options=Object.assign({},e,s),this.options.animation=Object.assign({},e.animation,null!==(n=s.animation)&&void 0!==n?n:{}),this.options.with_3d&&(this.options.with_3d=Object.assign({},i,!0===this.options.with_3d?{}:this.options.with_3d)),this.target.style.transformOrigin="center",this.start()}applyTranslation(t){this.target.animate([{transform:t}],{duration:this.options.animation.duration,fill:"forwards",easing:this.options.animation.ease})}getScreenRadius(){return Math.max(window.innerWidth,window.innerHeight)/2}getDeltaFromInvertion(t){const e={x:1,y:1};return!0===t?e.x=e.y=-1:"x"===t?e.x=-1:"y"===t&&(e.y=-1),e}createCircle(t,e){const i=document.createElement("div");return i.setAttribute("style",`\n position: absolute;\n background-color: transparent;\n width: ${2*t}px;\n aspect-ratio: 1/1;\n border: thin ${e} solid;\n border-radius: 100%;\n `.replace(/\n+/g,"").replace(/\s+/g," ")),i}debug(t="#e1e1e130"){this.target.parentElement.style.position="relative";const e=t=>{this.target.parentNode.insertBefore(t,this.target)};if(e(this.createCircle(this.options.elementRadius,t)),"full"!==this.options.detectionRadius){e(this.createCircle(this.options.detectionRadius,t))}}getTransformation(){const t=window.getComputedStyle(this.target).transform;let e=0,i=0,s=1,n=1;if(t&&"none"!==t){const o=/(matrix3d|matrix)\(([^)]+)\)/,a=t.match(o);if(a){const t=a[2].split(",").map(parseFloat);"matrix"===a[1]?(s=t[0],n=t[3],e=t[4],i=t[5]):"matrix3d"===a[1]&&(s=t[0],n=t[5],e=t[12],i=t[13])}}return{translationX:e,translationY:i,scaleX:s,scaleY:n}}update(t,e){var i,s,n;const o=this.target.getBoundingClientRect(),a=this.getTransformation(),r=o.width/a.scaleX,l=o.height/a.scaleY,d=o.left-a.translationX+r/2,h=o.top-a.translationY+l/2,[p,c]=[t-d,e-h],u=Math.sqrt(p*p+c*c);if("full"===this.options.detectionRadius||u<=this.options.detectionRadius){const t=[],e=Math.sqrt(p*p+c*c),n=0===e?0:p/e,o=0===e?0:c/e,a=e/("full"===this.options.detectionRadius?this.getScreenRadius():this.options.detectionRadius),r=this.options.elementRadius*a;if(this.options.with_3d){const e=this.options.with_3d,i=this.getDeltaFromInvertion(e.inverted),s=e.maxAngle*a;t.push(`perspective(${e.perspective}px)`),e.axe&&"x"!==e.axe||t.push(`rotateX(${o*s*i.x}deg)`),e.axe&&"y"!==e.axe||t.push(`rotateY(${-n*s*i.y}deg)`)}if(null===(i=this.options.scale)||void 0===i?void 0:i.to){const e=this.options.scale,i=null!==(s=e.from)&&void 0!==s?s:1;let n=e.to-i;e.animated&&(n*=a),t.push(`scale(${i+n})`)}const l=this.getDeltaFromInvertion(this.options.inverted),[d,h]=[n*r*l.x,o*r*l.y];this.options.axe&&"x"!==this.options.axe||t.push(`translateX(${d}px)`),this.options.axe&&"y"!==this.options.axe||t.push(`translateY(${h}px)`),this.applyTranslation(t.join(" "))}else(null===(n=this.options.scale)||void 0===n?void 0:n.from)?this.applyTranslation(`scale(${this.options.scale.from})`):this.applyTranslation("none")}start(){var e;this.target.style.willChange="transform",this.options.with_3d&&(this.target.style.transformStyle="preserve-3d"),(null===(e=this.options.scale)||void 0===e?void 0:e.from)&&(this.target.style.transform=`scale(${this.options.scale.from})`),t.push(this)}stop(){const e=t.findIndex((t=>t.target===this.target));-1!==e&&t.splice(e,1)}reset(){this.target.style.transform="none"}}}));
//# sourceMappingURL=index.js.map