Mouse following issue when using jquery fadeIn

Viewed 45

I am trying to have this circle follow the cursor. However I need the cursor to fade in after the user clicks a button, when this happens though the circle won't be centered on the cursor.

The first code snippet shows the desired result in terms of the circle following the cursor correctly and being centered.The second snippet shows the desired fade in on button click but as you can see the circle won't be centered on the cursor

First code snippet:

const cursor = document.querySelector('.test');
const {
  width,
  height
} = cursor.getBoundingClientRect();
document.addEventListener('mousemove', e => {
  cursor.style.top = e.y - height / 2 + 'px';
  cursor.style.left = e.x - width / 2 + 'px';
});
.test {
    position: absolute;
    width: 25rem;
    height: 25rem;
    border-radius: 50%;
    background-color: red;
    z-index: 200;
}
<div class="test"></div>

Second code snippet:

$("#myBtn").click(function(){
  $('.test').fadeIn();
}); 

const cursor = document.querySelector('.test');
const {
  width,
  height
} = cursor.getBoundingClientRect();
document.addEventListener('mousemove', e => {
  cursor.style.top = e.y - height / 2 + 'px';
  cursor.style.left = e.x - width / 2 + 'px';
});
.test {
    position: absolute;
    width: 25rem;
    height: 25rem;
    border-radius: 50%;
    background-color: blue;
    z-index: 200;
    display: none;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button id="myBtn">show</button>

<div class="test"></div>

2 Answers

In the second example, on page init the .test div has display: none, so its height and width are 0. You must calculate them after the fadeIn to get the correct result.

You can also add the mousemove listener after fadeIn:

$("#myBtn").click(function() {
  $('.test').fadeIn('slow', function() {
    const cursor = document.querySelector('.test')
    , { width, height } = cursor.getBoundingClientRect();
    
    document.addEventListener('mousemove', e => {
      cursor.style.top = e.y - height / 2 + 'px';
      cursor.style.left = e.x - width / 2 + 'px';
    });
  });
});
.test {
  position: absolute;
  width: 25rem;
  height: 25rem;
  border-radius: 50%;
  background-color: blue;
  z-index: 200;
  display: none;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button id="myBtn">show</button>

<div class="test"></div>

Another, perhaps simpler, alternative is just to call fadeOut() (with a duration of 0) on the .test div on page load, instead of using display:none

$("#myBtn").click(function(){
  $('.test').fadeIn();
}); 

const cursor = document.querySelector('.test');
const {
  width,
  height
} = cursor.getBoundingClientRect();

$('.test').fadeOut(0);

document.addEventListener('mousemove', e => {
  cursor.style.top = e.y - height / 2 + 'px';
  cursor.style.left = e.x - width / 2 + 'px';
});
.test {
    position: absolute;
    width: 25rem;
    height: 25rem;
    border-radius: 50%;
    background-color: blue;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<button id="myBtn">show</button>

<div class="test"></div>

Related