vue-magic-cursor
Version:
a customizable animated cursor for VueJS **[Demo Github Page](https://claronz.github.io/vue-magic-cursor/)**
2 lines (1 loc) • 4.68 kB
JavaScript
(function(r,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],o):(r=typeof globalThis<"u"?globalThis:r||self,o(r.MagicCursor={},r.Vue))})(this,function(r,o){"use strict";const h={name:"MagicCursor",props:{cursorVelocity:{type:Number,default:.5},followerVelocity:{type:Number,default:.1},idleTiming:{type:Number,default:1500},showFollower:{type:Boolean,default:!0},showCursor:{type:Boolean,default:!0},elementsToHover:{type:Array,default:()=>["a","button:not([disabled])","input:not([disabled])"]},hoverThrottle:{type:Number,default:500},hoverOutWaitTime:{type:Number,default:500}},data(){return{parentComponent:null,playing:!1,idleTimerId:null,animationId:null,throttleTimerId:null,isStopped:!0,isHover:!1,isDetached:!0,hoverOutWaitTimerId:null,cursorMouseX:0,cursorMouseY:0,followerMouseX:0,followerMouseY:0,cursorXPos:0,cursorYPos:0,followerXPos:0,followerYPos:0}},methods:{hoverEnterHandler(){this.isHover=!0},hoverLeaveHandler(){this.isHover=!1},detectHoverHandler(){this.elementsToHover.length&&this.parentComponent.querySelectorAll(this.elementsToHover.join(", ")).forEach(t=>{t.addEventListener("mouseover",this.hoverEnterHandler),t.addEventListener("mouseleave",this.hoverLeaveHandler)})},attachHoverHandler(){this.throttleTimerId=setInterval(this.detectHoverHandler,this.hoverThrottle)},attachCursor(){clearTimeout(this.hoverOutWaitTimerId),this.attachHoverHandler(),this.parentComponent.addEventListener("mousemove",this.moveCursor),this.isDetached&&requestAnimationFrame(this.render),this.isDetached=!1},detachCursor(){this.hoverOutWaitTimerId=setTimeout(()=>{this.isDetached=!0,clearInterval(this.throttleTimerId),cancelAnimationFrame(this.animationId),this.elementsToHover.length&&this.parentComponent.querySelectorAll(this.elementsToHover.join(", ")).forEach(t=>{t.removeEventListener("mouseover",this.hoverEnterHandler),t.removeEventListener("mouseleave",this.hoverLeaveHandler)})},this.idleTiming)},moveCursor(e){this.playing=!0,this.isStopped=!1;const t=e.clientX,i=e.clientY;if(this.showCursor){const s=this.$refs.cursor,l=s.offsetWidth/2,n=s.offsetHeight/2;this.cursorMouseX=t-l,this.cursorMouseY=i-n}if(this.showFollower){const s=this.$refs.follower,l=s.offsetWidth/2,n=s.offsetHeight/2;this.followerMouseX=t-l,this.followerMouseY=i-n}this.hideCursor()},hideCursor(){clearTimeout(this.idleTimerId),this.idleTimerId=setTimeout(this.mouseStopHandler,this.idleTiming)},mouseStopHandler(){this.isStopped=!0,this.playing=!1},render(){const e=this.$refs.cursor,t=this.$refs.follower;this.showCursor&&(this.cursorXPos+=(this.cursorMouseX-this.cursorXPos)*this.cursorVelocity,this.cursorYPos+=(this.cursorMouseY-this.cursorYPos)*this.cursorVelocity,e.style.transform="translate3d("+this.cursorXPos+"px,"+this.cursorYPos+"px, 0)"),this.showFollower&&(this.followerXPos+=(this.followerMouseX-this.followerXPos)*this.followerVelocity,this.followerYPos+=(this.followerMouseY-this.followerYPos)*this.followerVelocity,t.style.transform="translate3d("+this.followerXPos+"px,"+this.followerYPos+"px, 0)"),this.animationId=requestAnimationFrame(this.render)}},mounted(){this.parentComponent=this.$parent.$el,this.$parent.$el.addEventListener("mouseenter",this.attachCursor),this.$parent.$el.addEventListener("mouseleave",this.detachCursor),window.cancelAnimation=()=>{cancelAnimationFrame(this.animationId)}},beforeUnmount(){this.detachCursor()}},u=(e,t)=>{const i=e.__vccOpts||e;for(const[s,l]of t)i[s]=l;return i};function d(e,t,i,s,l,n){return o.openBlock(),o.createElementBlock(o.Fragment,null,[e.showCursor?(o.openBlock(),o.createElementBlock("div",{key:0,ref:"cursor",class:o.normalizeClass(["cursor",{"cursor--detached":e.isDetached}])},[o.renderSlot(e.$slots,"default",{isHover:e.isHover,isStopped:e.isStopped},()=>[o.createElementVNode("div",{class:o.normalizeClass(["cursor__pointer",{"cursor__pointer--hover":e.isHover,"cursor__pointer--stopped":e.isStopped}])},null,2)],!0)],2)):o.createCommentVNode("",!0),e.showFollower?(o.openBlock(),o.createElementBlock("div",{key:1,ref:"follower",class:o.normalizeClass(["cursor cursor--follower",{"cursor--detached":e.isDetached}])},[o.renderSlot(e.$slots,"follower",{isHover:e.isHover,isStopped:e.isStopped},()=>[o.createElementVNode("div",{class:o.normalizeClass(["cursor__follower",{"cursor__follower--hover":e.isHover,"cursor__follower--stopped":e.isStopped}])},null,2)],!0)],2)):o.createCommentVNode("",!0)],64)}const a=u(h,[["render",d],["__scopeId","data-v-c2325087"]]),c={install(e){e.component("MagicCursor",a)}};r.MagicCursor=a,r.default=c,Object.defineProperties(r,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});