<img src="//placehold.it/250x200" alt="" class="image">
<div class="circle-cursor circle-cursor--inner"></div>
<div class="circle-cursor circle-cursor--outer"></div>
body {
margin: 0;
--cursor-color: #000;
}
.circle-cursor {
position: fixed;
left: 0;
top: 0;
pointer-events: none;
border-radius: 50%;
transition: background-color 300ms;
}
.circle-cursor--inner {
width: 5px;
height: 5px;
left: -2.5px;
top: -2.5px;
z-index: 11000;
background-color: var(--cursor-color);
}
.circle-cursor--inner.circle-cursor--hover {
background-color: rgba(0,0,0,0);
}
.circle-cursor--outer {
width: 30px;
height: 30px;
left: -15px;
top: -15px;
border: 1px solid var(--cursor-color);
z-index: 12000;
opacity: 0.2;
}
.circle-cursor--outer.circle-cursor--hover {
background-color: var(--cursor-color);
}
const image = document.querySelector('.image');
const cursorInner = document.querySelector('.circle-cursor--inner');
const cursorOuter = document.querySelector('.circle-cursor--outer');
let mx = window.innerWidth / 2;
let my = window.innerHeight / 2;
let cxi = mx, cyi = my, cxo = mx, cyo = my;
window.addEventListener('mousemove', (event) => {
mx = event.clientX;
my = event.clientY;
});
function update() {
const dxi = (mx - cxi) * 0.2;
const dyi = (my - cyi) * 0.2;
cxi += dxi;
cyi += dyi;
const dxo = (mx - cxo) * 0.07;
const dyo = (my - cyo) * 0.07;
cxo += dxo;
cyo += dyo;
cursorOuter.style.transform = `translate(${cxo}px, ${cyo}px)`;
cursorInner.style.transform = `translate(${cxi}px, ${cyi}px)`;
requestAnimationFrame(update);
}
requestAnimationFrame(update);
image.addEventListener('mouseenter', () => {
cursorInner.classList.add('circle-cursor--hover');
cursorOuter.classList.add('circle-cursor--hover');
});
image.addEventListener('mouseleave', () => {
cursorInner.classList.remove('circle-cursor--hover');
cursorOuter.classList.remove('circle-cursor--hover');
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.