vue-magic-cursor
Version:
a customizable animated cursor for VueJS **[Demo Github Page](https://claronz.github.io/vue-magic-cursor/)**
147 lines (146 loc) • 5.56 kB
JavaScript
import { openBlock as n, createElementBlock as a, Fragment as c, normalizeClass as l, renderSlot as h, createElementVNode as u, createCommentVNode as d } from "vue";
const f = {
name: "MagicCursor",
props: {
cursorVelocity: { type: Number, default: 0.5 },
followerVelocity: { type: Number, default: 0.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,
// cursor position
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((o) => {
o.addEventListener("mouseover", this.hoverEnterHandler), o.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((o) => {
o.removeEventListener("mouseover", this.hoverEnterHandler), o.removeEventListener("mouseleave", this.hoverLeaveHandler);
});
}, this.idleTiming);
},
moveCursor(e) {
this.playing = !0, this.isStopped = !1;
const o = e.clientX, t = e.clientY;
if (this.showCursor) {
const r = this.$refs.cursor, s = r.offsetWidth / 2, i = r.offsetHeight / 2;
this.cursorMouseX = o - s, this.cursorMouseY = t - i;
}
if (this.showFollower) {
const r = this.$refs.follower, s = r.offsetWidth / 2, i = r.offsetHeight / 2;
this.followerMouseX = o - s, this.followerMouseY = t - i;
}
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, o = 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, o.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();
}
}, m = (e, o) => {
const t = e.__vccOpts || e;
for (const [r, s] of o)
t[r] = s;
return t;
};
function p(e, o, t, r, s, i) {
return n(), a(c, null, [
e.showCursor ? (n(), a("div", {
key: 0,
ref: "cursor",
class: l(["cursor", { "cursor--detached": e.isDetached }])
}, [
h(e.$slots, "default", {
isHover: e.isHover,
isStopped: e.isStopped
}, () => [
u("div", {
class: l(["cursor__pointer", {
"cursor__pointer--hover": e.isHover,
"cursor__pointer--stopped": e.isStopped
}])
}, null, 2)
], !0)
], 2)) : d("", !0),
e.showFollower ? (n(), a("div", {
key: 1,
ref: "follower",
class: l(["cursor cursor--follower", { "cursor--detached": e.isDetached }])
}, [
h(e.$slots, "follower", {
isHover: e.isHover,
isStopped: e.isStopped
}, () => [
u("div", {
class: l(["cursor__follower", {
"cursor__follower--hover": e.isHover,
"cursor__follower--stopped": e.isStopped
}])
}, null, 2)
], !0)
], 2)) : d("", !0)
], 64);
}
const v = /* @__PURE__ */ m(f, [["render", p], ["__scopeId", "data-v-c2325087"]]), H = {
install(e) {
e.component("MagicCursor", v);
}
};
export {
v as MagicCursor,
H as default
};