UNPKG

smooth-cursor

Version:

A customizable, physics-based smooth cursor animation component for React applications with spring animations, velocity tracking, and rotation effects

3 lines (2 loc) 3.24 kB
import{useSpring as e,motion as t}from"framer-motion";import r,{useState as n,useRef as a,useEffect as o}from"react";const s=()=>r.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:50,height:54,viewBox:"0 0 50 54",fill:"none",style:{scale:.5}},r.createElement("g",{filter:"url(#filter0_d_91_7928)"},r.createElement("path",{d:"M42.6817 41.1495L27.5103 6.79925C26.7269 5.02557 24.2082 5.02558 23.3927 6.79925L7.59814 41.1495C6.75833 42.9759 8.52712 44.8902 10.4125 44.1954L24.3757 39.0496C24.8829 38.8627 25.4385 38.8627 25.9422 39.0496L39.8121 44.1954C41.6849 44.8902 43.4884 42.9759 42.6817 41.1495Z",fill:"black"}),r.createElement("path",{d:"M43.7146 40.6933L28.5431 6.34306C27.3556 3.65428 23.5772 3.69516 22.3668 6.32755L6.57226 40.6778C5.3134 43.4156 7.97238 46.298 10.803 45.2549L24.7662 40.109C25.0221 40.0147 25.2999 40.0156 25.5494 40.1082L39.4193 45.254C42.2261 46.2953 44.9254 43.4347 43.7146 40.6933Z",stroke:"white",strokeWidth:2.25825})),r.createElement("defs",null,r.createElement("filter",{id:"filter0_d_91_7928",x:.602397,y:.952444,width:49.0584,height:52.428,filterUnits:"userSpaceOnUse",colorInterpolationFilters:"sRGB"},r.createElement("feFlood",{floodOpacity:0,result:"BackgroundImageFix"}),r.createElement("feColorMatrix",{in:"SourceAlpha",type:"matrix",values:"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0",result:"hardAlpha"}),r.createElement("feOffset",{dy:2.25825}),r.createElement("feGaussianBlur",{stdDeviation:2.25825}),r.createElement("feComposite",{in2:"hardAlpha",operator:"out"}),r.createElement("feColorMatrix",{type:"matrix",values:"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.08 0"}),r.createElement("feBlend",{mode:"normal",in2:"BackgroundImageFix",result:"effect1_dropShadow_91_7928"}),r.createElement("feBlend",{mode:"normal",in:"SourceGraphic",in2:"effect1_dropShadow_91_7928",result:"shape"})))),i=({cursor:i=r.createElement(s,null),springConfig:l={damping:45,stiffness:400,mass:1,restDelta:.001}})=>{const[c,m]=n(!1),u=a({x:0,y:0}),d=a({x:0,y:0}),f=a(Date.now()),p=a(0),h=a(0),x=e(0,l),y=e(0,l),w=e(0,{...l,damping:60,stiffness:300}),E=e(1,{...l,stiffness:500,damping:35});return o((()=>{const e=e=>{const t={x:e.clientX,y:e.clientY};(e=>{const t=Date.now(),r=t-f.current;r>0&&(d.current={x:(e.x-u.current.x)/r,y:(e.y-u.current.y)/r}),f.current=t,u.current=e})(t);const r=Math.sqrt(Math.pow(d.current.x,2)+Math.pow(d.current.y,2));if(x.set(t.x),y.set(t.y),r>.1){const e=Math.atan2(d.current.y,d.current.x)*(180/Math.PI)+90;let t=e-p.current;t>180&&(t-=360),t<-180&&(t+=360),h.current+=t,w.set(h.current),p.current=e,E.set(.95),m(!0);const r=setTimeout((()=>{E.set(1),m(!1)}),150);return()=>clearTimeout(r)}};let t;const r=r=>{t||(t=requestAnimationFrame((()=>{e(r),t=0})))};return document.body.style.cursor="none",window.addEventListener("mousemove",r),()=>{window.removeEventListener("mousemove",r),document.body.style.cursor="auto",t&&cancelAnimationFrame(t)}}),[x,y,w,E]),r.createElement(t.div,{style:{position:"fixed",left:x,top:y,translateX:"-50%",translateY:"-50%",rotate:w,scale:E,zIndex:100,pointerEvents:"none",willChange:"transform"},initial:{scale:0},animate:{scale:1},transition:{type:"spring",stiffness:400,damping:30}},i)};export{i as SmoothCursor}; //# sourceMappingURL=index.js.map