<body>
<div class="demo-2"><a href="#">blog kinsdayz cursor demo</a></div>
<div class="circle-cursor circle-cursor-outer">
<img width="50px" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNNS4zNDQgMTkuNDQybC0xLjE4NiAxLjYyOGMtMi4zMDUtMS45OTUtMy44NDItNC44NS00LjEwNy04LjA3aDJjLjI1NSAyLjU1MyAxLjQ4IDQuODE5IDMuMjkzIDYuNDQyem0xNi42MDUtNi40NDJjLS4yNTYgMi41Ni0xLjQ4NyA0LjgzMS0zLjMwOCA2LjQ1NWwxLjE4MyAxLjYzMWMyLjMxNS0xLjk5NyAzLjg1OC00Ljg1OCA0LjEyNS04LjA4NmgtMnptLTE5Ljg5OC0yYy4yNTYtMi41NjEgMS40ODctNC44MzIgMy4zMDktNi40NTZsLTEuMTgzLTEuNjMxYy0yLjMxNyAxLjk5Ni0zLjg2IDQuODU4LTQuMTI2IDguMDg3aDJ6bTQuOTI3LTcuNjMzYzEuNDc3LS44NjQgMy4xOS0xLjM2NyA1LjAyMi0xLjM2NyAxLjgzOSAwIDMuNTU4LjUwNyA1LjAzOSAxLjM3N2wxLjE4My0xLjYyNGMtMS44MTctMS4xMDUtMy45NDEtMS43NTMtNi4yMjItMS43NTMtMi4yNzIgMC00LjM5LjY0NC02LjIwMSAxLjc0MWwxLjE3OSAxLjYyNnptMTIuODYzLS40MzhsLTEuMTg2IDEuNjI4YzEuODEzIDEuNjI0IDMuMDM5IDMuODg5IDMuMjk0IDYuNDQzaDJjLS4yNjUtMy4yMjEtMS44MDItNi4wNzYtNC4xMDgtOC4wNzF6bS0yLjgxNyAxNy43MDNjLTEuNDc4Ljg2NC0zLjE5MiAxLjM2OC01LjAyNCAxLjM2OC0xLjg0IDAtMy41Ni0uNTA4LTUuMDQyLTEuMzc4bC0xLjE4MyAxLjYyNGMxLjgxOCAxLjEwNiAzLjk0MyAxLjc1NCA2LjIyNSAxLjc1NCAyLjI3MyAwIDQuMzkyLS42NDQgNi4yMDMtMS43NDJsLTEuMTc5LTEuNjI2eiIvPjwvc3ZnPg==">
</div>
<div class="circle-cursor circle-cursor-inner"></div>
<div class="demo-1"></div>
</body>
body{
height: 100vh;
background:#AAAEBC;
}
a { color: #7A5D45; font-weight:700; text-decoration: none; }
.circle-cursor {
position: fixed;
left: 0;
top: 0;
pointer-events: none;
border-radius: 100%;
}
.circle-cursor-outer-badge {
opacity: 0.5;
transition: all 500ms ease-out;
}
.circle-cursor-inner {
width: 22.5px;
height: 22.5px;
left: -11.25px;
top: -11.25px;
z-index: 11000;
mix-blend-mode: difference;
background: white;
}
.demo-1 { height:50vh; background-color:#fff;}
.demo-2 { margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); }
class Demo {
constructor() {
this.initCursor();
this.initHovers();
}
initCursor() {
const { Back } = window;
this.outerCursor = document.querySelector(".circle-cursor-outer");
this.innerCursor = document.querySelector(".circle-cursor-inner");
this.outerCursorBox = this.outerCursor.getBoundingClientRect();
this.outerCursorSpeed = 0;
this.easing = Back.easeOut.config(1.7);
this.clientX = -100;
this.clientY = -100;
this.showCursor = false;
const unveilCursor = () => {
TweenMax.set(this.innerCursor, {
x: this.clientX,
y: this.clientY
});
TweenMax.set(this.outerCursor, {
x: this.clientX - this.outerCursorBox.width / 2,
y: this.clientY - this.outerCursorBox.height / 2
});
setTimeout(() => {
this.outerCursorSpeed = 0.2;
}, 100);
this.showCursor = true;
};
document.addEventListener("mousemove", unveilCursor);
document.addEventListener("mousemove", e => {
this.clientX = e.clientX;
this.clientY = e.clientY;
});
const render = () => {
TweenMax.set(this.innerCursor, {
rotation: 90,
x: this.clientX,
y: this.clientY
});
if (!this.isStuck) {
TweenMax.to(this.outerCursor, this.outerCursorSpeed, {
x: this.clientX - this.outerCursorBox.width / 2,
y: this.clientY - this.outerCursorBox.height / 2
});
}
if (this.showCursor) {
document.removeEventListener("mousemove", unveilCursor);
}
requestAnimationFrame(render);
};
requestAnimationFrame(render);
}
initHovers() {
const handleMouseEnter = e => {
this.isStuck = true;
const target = e.currentTarget;
const box = target.getBoundingClientRect();
this.outerCursorOriginals = {
width: this.outerCursorBox.width,
height: this.outerCursorBox.height
};
TweenMax.to(this.innerCursor, 0.2, {
x: box.left,
y: box.top,
width: box.width,
height: box.height,
opacity: 0.4,
});
};
const handleMouseLeave = () => {
this.isStuck = false;
TweenMax.to(this.innerCursor, 0.2, {
width: this.outerCursorOriginals.width,
height: this.outerCursorOriginals.height,
opacity: 0.2,
});
};
const mainNavHoverTween = TweenMax.to(this.innerCursor, 0.3, {
ease: this.easing,
paused: true,
opacity: 1,
width: 70,
height: 70,
left: -35,
top: -35
});
const mainNavMouseEnter = () => {
this.outerCursorSpeed = 0;
TweenMax.set(this.innerCursor, { opacity: 1 });
mainNavHoverTween.play();
};
const mainNavMouseLeave = () => {
this.outerCursorSpeed = 0.2;
TweenMax.set(this.innerCursor, { opacity: 1 });
mainNavHoverTween.reverse();
};
const mainNavLinks = document.querySelectorAll("a");
mainNavLinks.forEach(item => {
item.addEventListener("mouseenter", mainNavMouseEnter);
item.addEventListener("mouseleave", mainNavMouseLeave);
});
}
}
const demo = new Demo();
This Pen doesn't use any external CSS resources.