0

I have a custom cursor on my site that is working perfectly apart from one thing. When clicking through to a new page, when the page loads the cursor resets itself to the top left of the page regardless of where you leave the mouse on the page, then once you moved the mouse the cursor moves back to where the mouse is. I have tried removing "top" & "left" from the CSS but the problem remains. I cant see what is causing this to happen, and I just need the cursor to stay where the mouse is positioned on the page and not reset every time you navigate to a new page.

jQuery(document).ready(function($) {
let cursor = document.querySelector('#custom-cursor');

    if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
    $('#custom-cursor').remove();
}
else { cursor.style.display = 'block';}

document.addEventListener('mousemove', evt => {
    
  let { clientX: x, clientY: y } = evt;
  let scale = 1;
  
  if (evt.target.matches('a,span,[onclick],img,video,i')) {
    cursor.classList.add('active');
    scale = 0.5;
  } else {
    cursor.classList.remove('active');
  }
  
  cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;
  
});
});
* {
  cursor: none;
}

#custom-cursor {
  display: none;
  position: fixed;
  width: 20px; height: 20px;
  top: -10px;
  left: -10px;
  border: 2px solid black;
  border-radius: 50%;
  opacity: 1;
  background-color: #fb4d98;
  pointer-events: none;
  z-index: 99999999;
  transition:
    transform ease-out 0.15s,
    border 0.5s,
    opacity 0.5s,
    background-color 0.5s;
}
#custom-cursor.active {
  opacity: 0.5;
  background-color: #000;
  border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>
gjjr
  • 607
  • 5
  • 13
  • You have to get cursor position and that, unfortunately, [is not possible](https://stackoverflow.com/questions/2601097/how-to-get-the-mouse-position-without-events-without-moving-the-mouse). – jiwopene Jul 26 '21 at 14:11

2 Answers2

1

Use ordinary CSS cursor as shown in the other answer and replace it with you fancy cursor in the first mouse event:

jQuery(document).ready(function($) {
  let cursor = document.querySelector('#custom-cursor');

  document.addEventListener('mousemove', evt => {
    document.body.classList.add('custom-cursor-moved')

    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
      $('#custom-cursor').remove();
    } else {
      cursor.style.display = 'block';
    }


    let {
      clientX: x,
      clientY: y
    } = evt;
    let scale = 1;

    if (evt.target.matches('a,span,[onclick],img,video,i')) {
      cursor.classList.add('active');
      scale = 0.5;
    } else {
      cursor.classList.remove('active');
    }

    cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;

  });
});
body {
  height: 100vh;
}

html,
body {
  margin: 0;
  padding: 0;
}

* {
  cursor: url(https://i.stack.imgur.com/7pmmV.png) 0 0, auto;
}

.custom-cursor-moved,
.custom-cursor-moved * {
  cursor: none !important;
}

#custom-cursor {
  display: none;
  position: fixed;
  width: 20px;
  height: 20px;
  top: -10px;
  left: -10px;
  border: 2px solid black;
  border-radius: 50%;
  opacity: 1;
  background-color: #fb4d98;
  pointer-events: none;
  z-index: 99999999;
  transition: transform ease-out 0.15s, border 0.5s, opacity 0.5s, background-color 0.5s;
}

#custom-cursor.active {
  opacity: 0.5;
  background-color: #000;
  border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>

Try me.<br> Try me.

It needs a bit of modifications (better cursor image, fix it hotspot etc.) but it works.

Be very, very careful when doing such thing. Try to not break any accessibility tools and please do not assume that Android/some specific user-agent HAS touchscreen, etc.. Use proper APIs.

jiwopene
  • 3,077
  • 17
  • 30
  • Cool thanks for this, Ideally i really need the cursor to remain visible always, but this is a work around for the time being while I investigate further. – gjjr Jul 26 '21 at 15:32
0

Use CSS cursor property instead:

html {
  cursor: url(https://cdn.sstatic.net/Sites/stackoverflow/Img/favicon.ico?v=ec617d715196) 0 0, auto;
  height: 100%;
}
Try me.
jiwopene
  • 3,077
  • 17
  • 30
  • The problem is i need to use the CSS cursor styling rather than an image – gjjr Jul 26 '21 at 14:32
  • You would have to get the cursor position *before* the first mouse event and [that is not possible](https://stackoverflow.com/questions/2601097/how-to-get-the-mouse-position-without-events-without-moving-the-mouse). Using CSS cursor is probably the only option. – jiwopene Jul 26 '21 at 14:37
  • If you look at [this website](https://www.wearebulletproof.com/) you can see it has a similar cursors, that from what I can see is being styled using CSS and doesnt have the issue of resetting to the top corner each time you navigate between pages. – gjjr Jul 26 '21 at 14:47
  • They are storing the last position in a cookie. It is quite dirty and brittle solution and it might break in some circumstances (opening page in new tab, having disabled cookies, closing and then opening page etc.). – jiwopene Jul 26 '21 at 15:03
  • What do you think about using browser-provided cursor and switching to your cursor on the first mouse event? – jiwopene Jul 26 '21 at 15:07
  • Ok I see, yes I could try that I suppose – gjjr Jul 26 '21 at 15:09
  • See the new answer for example. – jiwopene Jul 26 '21 at 15:24