I am trying to create a custom cursor that changes when hovering over a <div>
, but there is a flicker when moving left to right across it, but not when moving right to left. Why this is happening and what I can do to fix it?
document.addEventListener('mousemove', (ev) => cursorMove(ev));
function cursorMove(ev) {
let circle = document.getElementById('circle');
let posY = ev.clientY;
let posX = ev.clientX;
circle.style.top = posY + 'px';
circle.style.left = posX + 'px';
}
body {
margin: 0;
height: 100vh;
background-color: #acd1d2;
position: relative;
display: flex;
justify-content: center;
align-items: center;
font-family: monospace;
}
#wrapper {
position: relative;
width: 70%;
height: 80%;
}
.box {
height: 25%;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
#box-1 {
background-color: #e8edf3;
}
#box-1:hover ~ #circle {
background-color: #e6cf8b;
box-shadow:inset 0em -0.3em 0.4em 0.2em #ca9e03a6;
}
#box-2 {
background-color: #e6cf8b;
}
#box-2:hover ~ #circle {
background-color: transparent;
border: 3px solid #E91E63;
}
#box-3 {
background-color: #b56969;
}
#box-3:hover ~ #circle {
height: 1em;
width: 1em;
background-color: #e6cf8b;
}
#box-4 {
background-color: #22264b;
color: white;
}
#box-4:hover ~ #circle {
background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);
}
#circle {
position: fixed;
border-radius: 50%;
z-index: 5;
height: 32px;
width: 32px;
background-color: white;
}
<div id="wrapper">
<div id="box-1" class="box">Sphere</div>
<div id="box-2" class="box">Circle outline</div>
<div id="box-3" class="box">Circle pin</div>
<div id="box-4" class="box">Circle color gradient</div>
<div id="circle"></div>
</div>
That's because your mouse moves faster than the circle and you hover over it, so the styles that apply to it are the same ones than when the cursor is on the background green/blue-ish area of the page.
You can fix that by adding
pointer-events: none
to the circle so that it feels a bit like this:Ok, where were we? Oh yes... So you should use
position: fixed
instead ofabsolute
(as you really want your cursor to be positioned relative to the top-left corner of the viewport) and probablywindow.requestAnimationFrame
to get a smoother animation andtranslate3d(0, 0, 0)
to promote the element to its own layer and enable hardware-accelerated rendering, which will also contribute to make it feel smoother.You could also hide the default cursor with
cursor: none
and center the circle where the arrowhead of the cursor is to make it feel just like a real cursor.Here you can see another cool example I made of a custom cursor using CSS that resembles a torch: How to darken a CSS background image but keep area around cursor brighter.
Also, you can check out the cursor on my website, which is quite similar to what you have done as it has animations/transitions between its different shapes or states.
Check it out here: https://gmzcodes.com/.
Check the code here: https://github.com/Danziger/gmzcodes