Problem
I haven't been able to test this on MS Edge but Chrome and Firefox appear absolutely fine. My cursor uses two divs, one where the cursor/point would be, and a 2nd div which is follows the cursor with a bit of a delay/drag.
It's the 2nd div that seems to have a problem in Safari. When moving the mouse the 2nd (trailing) cursor shakes around and seems to have trouble tracking the cursor until you stop moving the mouse - when it jumps into the correct place.
It looks like maybe Safari is having trouble handling the transition: all .12s ease-out;
? Could it be how that works with the following?
document.addEventListener('mousemove', function(e) {
cursor.style.transform = `translate3d(calc(${e.clientX}px - 50%), calc(${e.clientY}px - 50%), 0)`;
});
CodePen
I'll add the JS to the post but I also have it on this CodePen: https://codepen.io/moy/pen/mdpVrgM
Can anyone see anything fundamentally wrong with this?
I thought it might work better if the cursor divs were nested instead of separate - but that seems to totally screw the offset to the main pointer.
As an aside...
I have two separate blocks of code for a.forEach
, one for 'default' links and the other for ones with a data
attribute. Is that ok? Or should I use a data
attribute for everything including default a
links? Just wondering what is more efficient?
var cursor = document.querySelector('.cursor');
var cursorinner = document.querySelector('.cursor2');
var a = document.querySelectorAll('a');
document.addEventListener('mousemove', function(e) {
cursor.style.transform = `translate3d(calc(${e.clientX}px - 50%), calc(${e.clientY}px - 50%), 0)`;
});
document.addEventListener('mousemove', function(e) {
var x = e.clientX;
var y = e.clientY;
cursorinner.style.left = x + 'px';
cursorinner.style.top = y + 'px';
});
document.addEventListener('mousedown', function() {
cursor.classList.add('click');
cursorinner.classList.add('cursorinnerhover');
});
document.addEventListener('mouseup', function() {
cursor.classList.remove('click');
cursorinner.classList.remove('cursorinnerhover');
});
a.forEach(item => {
item.addEventListener('mouseover', () => {
cursor.classList.add('hover');
});
item.addEventListener('mouseleave', () => {
cursor.classList.remove('hover');
});
});
a.forEach((item) => {
const interaction = item.dataset.interaction;
item.addEventListener("mouseover", () => {
cursorinner.classList.add(interaction);
});
item.addEventListener("mouseleave", () => {
cursorinner.classList.remove(interaction);
});
});
body, html {
width: 100%;
height: 100%;
}
section {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-direction: column;
}
/* Cursor Stuff */
* {
cursor: none;
}
.cursor {
border: 2px solid black;
border-radius: 100%;
box-sizing: border-box;
height: 32px;
pointer-events: none;
position: fixed;
top: 0;
left: 0;
transform: translate(-50%, -50%);
transition: all .12s ease-out;
width: 32px;
z-index: 100;
}
.cursor2 {
background-color: black;
border-radius: 100%;
/* height: 4px; */
height: 12px;
opacity: 1;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
transition: height .12s, opacity .12s, width .12s;
/* width: 4px; */
width: 12px;
z-index: 100;
}
.hover {
height: 4px;
opacity: 0;
width: 4px;
}
.cursorinnerhover {
height: 0;
width: 0;
}
/* Data Interaction Changes */
.red {background: red;}
.green {background: green;}
.blue {background: blue;}
<div class="cursor"></div>
<div class="cursor2"></div>
<section>
<a href="#" data-interaction="red">Hover Me</a>
<br />
<a href="#" data-interaction="green">Hover Me</a>
<br />
<a href="#" data-interaction="blue">Hover Me</a>
</section>