The simplest and easiest way.
body, a {
cursor: url(https://url-of-your-image.svg), auto;
}
More flexibility, simple implementation - sometimes janky
.custom-cursor {
position: fixed;
top: 0;
left: 0;
z-index: 999;
transform: translate(-50%, -50%);
pointer-events: none;
}
More flexibility - harder to implement
.js-cursor {
position: fixed;
top: 0;
left: 0;
z-index: 999;
transform: translate(-50%, -50%);
pointer-events: none;
}
const cursor = document.querySelector('.js-cursor')
window.addEventListener('mousemove', (e)=> {
cursor.style.top = e.y + 'px'
cursor.style.left = e.x + 'px'
})
More flexibility & better performance - harder to implement
.gsap-cursor {
position: fixed;
top: 0;
left: 0;
z-index: 999;
transform: translate(-50%, -50%);
pointer-events: none;
}
// if you want it to delay a but behind your mouse movements
const cursor = document.querySelector('.gsap-cursor')
const xTo = gsap.quickTo(cursor, 'x', {
duration: 0.3,
ease: 'power3.out'
})
const yTo = gsap.quickTo(cursor, 'y', {
duration: 0.3,
ease: 'power3.out'
})
window.addEventListener('mousemove', (e) => {
xTo(e.x)
yTo(e.y)
})
// if you want it to directly follow your movements
const cursor = document.querySelector('.gsap-cursor')
const xSetter = gsap.quickSetter(cursor, 'x', 'px')
const ySetter = gsap.quickSetter(cursor, 'y', 'px')
window.addEventListener('mousemove', (e) => {
xSetter(e.x)
ySetter(e.y)
})