cursor-style
Version:
Multiple prebuilt cursor styles to choose from
3 lines (2 loc) • 6.83 kB
JavaScript
import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import{useState as r,useRef as i,useEffect as o,useCallback as c}from"react";import{createPortal as l}from"react-dom";const s=(e,t,n)=>(1-n)*e+n*t,a=(e=0,t)=>{const[n,c]=r(t),l=i(0),a=i(t);return o((()=>{const t=t=>{a.current={x:t.clientX,y:t.clientY},0===e&&c(a.current)};return window.addEventListener("mousemove",t),()=>{window.removeEventListener("mousemove",t)}}),[e]),o((()=>{if(0===e)return;const t=()=>{const r=1-.09*e,i=s(n.x,a.current.x,r),o=s(n.y,a.current.y,r);c({x:i,y:o}),l.current=requestAnimationFrame(t)};return l.current=requestAnimationFrame(t),()=>{cancelAnimationFrame(l.current)}}),[n,e]),{position:n}};function f(e="a, button, input, textarea, [role='button'], [tabindex]:not([tabindex='-1']), .hoverable"){const[t,n]=r(!1);return o((()=>{function t(t){const r=document.elementFromPoint(t.clientX,t.clientY);if(!r)return void n(!1);let i=!1;try{i=r.matches(e)}catch{i=!1}n(i)}return document.addEventListener("mousemove",t),()=>{document.removeEventListener("mousemove",t)}}),[e]),t}const d={position:"fixed",width:"20px",height:"20px",backgroundColor:"white",borderRadius:"50%",pointerEvents:"none",mixBlendMode:"difference",cursor:"none",transition:"transform 0.2s ease",zIndex:2147483647};let u=[];const m=()=>({triggerClickEffect:c(((e,t,n="pulse",r="white",i=1.5,o=300)=>{u.forEach((c=>c({x:e,y:t,type:n,color:r,size:i,duration:o})))}),[]),subscribe:e=>(u.push(e),()=>{u=u.filter((t=>t!==e))})});let p=0,x=!1;const E=()=>{const{subscribe:n}=m(),[i,c]=r([]),[s,a]=r(null);return o((()=>{!function(){if(x)return;const e=document.createElement("style");e.textContent="\n @keyframes cursor-pulse {\n 0% { transform: translate(-50%, -50%) scale(1); opacity: 1; }\n 100% { transform: translate(-50%, -50%) scale(2); opacity: 0; }\n }\n .click-effect-pulse {\n animation-name: cursor-pulse;\n animation-timing-function: ease-out;\n animation-fill-mode: forwards;\n transform-origin: center center; /* <-- add this */\n }\n ",document.head.appendChild(e),x=!0}();let e=document.getElementById("cursor-click-effects");e||(e=document.createElement("div"),e.id="cursor-click-effects",document.body.appendChild(e)),a(e);const t=n((({x:e,y:t,type:n,color:r,size:i,duration:o})=>{const l=p++;c((c=>[...c,{id:l,x:e,y:t,type:n,color:r,size:i,duration:o}])),setTimeout((()=>{c((e=>e.filter((e=>e.id!==l))))}),o)}));return()=>t()}),[n]),s?l(e(t,{children:i.map((({id:t,x:n,y:r,type:i,color:o,size:c,duration:l})=>{const s=2*c;return e("div",{className:`click-effect-${i}`,style:{position:"fixed",left:`${n}px`,top:`${r}px`,width:`${s}px`,height:`${s}px`,transform:"translate(-50%, -50%)",opacity:.5,borderRadius:"50%",backgroundColor:o,pointerEvents:"none",zIndex:2147483647,animationDuration:`${l}ms`,animationName:"cursor-pulse",animationTimingFunction:"ease-out",animationFillMode:"forwards"}},t)}))}),s):null};if("undefined"!=typeof window&&!document.getElementById("cursor-click-effects-root")){const t=document.createElement("div");t.id="cursor-click-effects-root",document.body.appendChild(t),import("react-dom/client").then((({createRoot:n})=>{n(t).render(e(E,{}))}))}const k=({delay:t,size:n=20,bgColor:r="white",useMixBlendDifference:i=!0,scaleOnHover:c=1.5,clickEffect:l,clickEffectColor:s="white",clickEffectSize:u=10,clickEffectDuration:p=300})=>{const x=f(),{position:E}=a(t,{x:0,y:0}),{triggerClickEffect:k}=m();return o((()=>{if(!l)return;const e=e=>{k(e.clientX,e.clientY,l,s,u,p)};return window.addEventListener("click",e),()=>window.removeEventListener("click",e)}),[l,s,u,p]),e("div",{className:"cursor",style:{...d,width:`${n}px`,height:`${n}px`,left:`${E.x}px`,top:`${E.y}px`,backgroundColor:r,mixBlendMode:i?"difference":"normal",transform:`translate(-50%, -50%) scale(${x?c:1})`}})},y=({delay:r,size:c,sizeDot:l=c||10,sizeOutline:s=c||45,bgColorDot:d="white",bgColorOutline:u="white",useMixBlendDifference:p=!0,scaleOnHover:x=1.5,clickEffect:E,clickEffectColor:k=d,clickEffectSize:y=1.5,clickEffectDuration:v=300})=>{const h=i(null),w=i(null),{position:g}=a(r,{x:0,y:0}),b=f(),{triggerClickEffect:C}=m();o((()=>{const e=e=>{h.current&&(h.current.style.left=`${e.clientX}px`,h.current.style.top=`${e.clientY}px`,h.current.style.transform=`translate(-50%, -50%) scale(${b?x:1})`)};return window.addEventListener("mousemove",e),()=>window.removeEventListener("mousemove",e)}),[b,x]),o((()=>{w.current&&(w.current.style.left=`${g.x}px`,w.current.style.top=`${g.y}px`,w.current.style.transform=`translate(-50%, -50%) scale(${b?x:1})`)}),[g,b,x]),o((()=>{if(!E)return;const e=e=>{C(e.clientX,e.clientY,E,k,y,v)};return window.addEventListener("click",e),()=>window.removeEventListener("click",e)}),[E,k,y,v]);const $=p?"difference":"normal";return n(t,{children:[e("div",{ref:h,className:"cursor",style:{width:`${l}px`,height:`${l}px`,backgroundColor:d,mixBlendMode:$,zIndex:9999,borderRadius:"50%",transition:"transform 0.2s ease",position:"fixed",pointerEvents:"none"}}),e("div",{ref:w,className:"cursor",style:{width:`${s}px`,height:`${s}px`,border:`2px solid ${u}`,backgroundColor:"transparent",mixBlendMode:$,zIndex:9998,borderRadius:"50%",transition:"transform 0.2s ease",position:"fixed",pointerEvents:"none"}})]})},v=({delay:t,size:n=35,bgColor:r="white",useMixBlendDifference:i=!0,scaleOnHover:c=1.5,clickEffect:l,clickEffectColor:s="white",clickEffectDuration:u=300,clickEffectSize:p=1.5})=>{const{position:x}=a(t,{x:0,y:0}),E=f(),{triggerClickEffect:k}=m();return o((()=>{if(!l)return;const e=e=>{k(e.clientX,e.clientY,l,s,p,u)};return window.addEventListener("click",e),()=>window.removeEventListener("click",e)}),[l,s,p,u]),e("div",{className:"cursor",style:{...d,left:`${x.x}px`,top:`${x.y}px`,border:`2px solid ${r}`,transform:`translate(-50%, -50%) scale(${E?c:1})`,width:`${n}px`,height:`${n}px`,mixBlendMode:i?"difference":"normal",backgroundColor:"transparent"}})},h=({type:t,delay:n=0,size:r,sizeDot:i,sizeOutline:o,bgColor:c,bgColorDot:l,bgColorOutline:s,useMixBlendDifference:a,scaleOnHover:f,clickEffect:d,clickEffectColor:u,clickEffectSize:m,clickEffectDuration:p})=>{const x=Math.max(0,Math.min(n,1e3));switch(t){case"one":return e(k,{delay:x,size:r,bgColor:c,useMixBlendDifference:a,scaleOnHover:f,clickEffect:d,clickEffectColor:u,clickEffectSize:m,clickEffectDuration:p});case"two":return e(y,{delay:x,sizeDot:i,sizeOutline:o,bgColorDot:l,bgColorOutline:s,useMixBlendDifference:a,scaleOnHover:f,clickEffect:d,clickEffectColor:u,clickEffectSize:m,clickEffectDuration:p});case"three":return e(v,{delay:x,size:r,bgColor:c,useMixBlendDifference:a,scaleOnHover:f,clickEffect:d,clickEffectColor:u,clickEffectSize:m,clickEffectDuration:p});default:return null}};export{k as CursorOne,v as CursorThree,y as CursorTwo,h as CustomCursor};
//# sourceMappingURL=index.js.map