Optimise Javascript cursor so it runs smoother (mainly Safari)

But it is possible to use more than one svg image and use css or js to create the effect you want using svg properties.
This codepen shows a similar effect

1 Like

Nice demo :+1:

Unfortunately that brings us back to square one with regards to the older Safari version mentioned at the beginning of the thread and was the main problem to be solved :slight_smile: That demo is once again a bit laggy in my Safari (unlike my revised demo) and not really usable except for a nice effect to look at. You couldn’t use it to select things as the point of the trail doesn’t keep up with the mouse position in Safari. (That demo is also using the greensock library to achieve that effect so would be another overhead to consider.)

However, I think you had a point with your original comment about actually using a cursor image but we would still need to track the cursor and also apply the outer circle using a css element (no need for an image for a simple circle).

Therefore I think it would be worth a try in using a cursor image for the small dot in the center and then using the existing routine for the follow around circle. The circle only needs to track the cursor position from JS and the delay is catered for in the css transition. If I get a chance I’ll have a go later (assuming I know what I’m talking about) :slight_smile:

Couldn’t be bothered creating the svg/cursor image/data-uri so just went for the standard crosshair instead.:slight_smile:

It would be the same approach for a custom cursor image.

1 Like

@PaulOB yeah the canvas stuff is a bit beyond me too - but that previous example is cool!

The last CodePen responses really great and the JS looks like it’s been reduced. I might see if I can apply the outer circle to a before/after element so the actually .cursor div can be the dot.

Then try and work it into my original UI so I can extend the JS to include the classes for hover + try and get the different hover effects working/morphing

Do you think we’d still have an issue rotating the arrow due to the transform being in the JS? I guess if we get that far, maybe I just need to add some extra code so it uses a different transform, including rotation when that particular class is added.

Will try and update with an example asap! Thanks again! :slight_smile:

1 Like

Actually scratch that. I don’t think the delay is going to work on a before/after element, both the .cursor and . Nor will a nested, 2nd div as it will just move at the same delay as the parent. I guess that’s what there were 2 divs originally.

Will investigate further!

Yes that makes it easy for one to follow the other as all you need is the same positions but a delay on the second item.

Yes the JS would over-ride the transform.

You could add an inner element for the arrow and rotate that instead. Then the js just moves the outer element and doesn’t interfere with the arrow’s rotation. Css and html will need to be adjusted of course but should be relatively simple.

1 Like

Ok aside from the rotating the right arrow - I think this is pretty close to the original now. I had to add some margins on hover so when items reduced in size they did so centred - as we can’t use calc/transform/transform-origin.

A couple of things I noticed, nothing major but just for some feedback…

  • I’ve left the default pointer on to show there’s a bit of lag on the main/dot pointer. Is that something I’ve done? Not vital as you won’t notice without default pointer but wondered if it could be corrected or reduced?
  • Hovering over the image and moving the arrow around, does it appear to go ‘fuzzy’ occasionally for anyone?

I tried desperately to use a before/after pseudo element for the outer circle, which works! But couldn’t get the delay effect working, I use it doesn’t work on child elements. That was the only issue though, so had to revert to 2 divs.

To get the arrow to rotate, I’ll look at added a div within .cursor but seems like a lot of div’s now.

Out of curiosity …and my head is a bit frazzled and I’ve forgotten where we are now haha. I wondered if we reintroduced the left/top positioning now we’ve optimised everything would performance take a massive hit again? Or is that the main issue with Safari we need to stay away from? Was just thinking if that worked now, maybe it’d free up the need for extra divs on the cursor - but if I style a nested div, I guess that frees up transform/calc etc on that child element.

Top and left are always going to have a performance hit unlike transform and is recommended you don’t use them in intensive situations.

I think the main culprit in Safari was using calc in the js so you’d probably need to test whether top and left were acceptable.

Thanks @PaulOB if transform is better for performance I’ll definitely stick with that then and just use the extra child div/span.

Going to call it a night back pick up tomorrow but I think I have the bones of it working here: https://codepen.io/moy/pen/rNdaVYM

Rotate works in principle but it’s freaking out a bit due to the movement/size of the container I think. So probably need to have a play around with what is set on what. Might be related to the real cursor moving a bit ahead of the .cursor element. Looks like it’s having trouble recognising it’s over/leaving the link.

Edit: Scratch that! Not sure if it’s ideal but adding position: fixed onto the child span element as well as the parent .cursor seems to have resolved the issue. Will test more tomorrow :slight_smile:

That looks pretty good :slight_smile:

One thing is that it’s hard to see the arrow over the image so maybe do something like this.

.cursor-prev span,
.cursor-next span{
  box-shadow:0 0 20px 20px rgba(255,255,255,0.3);

Just an idea :slight_smile:

Yeah I think that might be needs. It’s not as big an issue on the ‘real’ images but would be good to add just incase as it’s not legible on those placeholders!

This is my noob-ness but can I ask what timeout = null; does? I noticed I’ve put it in twice but I assume I actually just need it once above both of the .style.transform bits?

Lastly, the ‘dot’ follows with a bit of delay behind the real cursor. Is that something I’ve doneo r just one of those things? Once the default cursor is disabled you won’t notice really but I just wondered. Definitely don’t want to mess with performance and add a load of code just for that.

Fingers cross this works just as good when I drop it on the actual page it’s intended for! :smile: :crossed_fingers:

That resets the timeout so that it waits the specified time before going again. You only need the first one.

That’s because of the timeout slowing it down. In my example I kept the dot out of the timeout routine as it wasn’t really causing an issue.

e.g.From one of my earlier examples.

  function (e) {
    var x = e.clientX;
    var y = e.clientY;
    cursorInner.style.transform = `translate3d(${x - 0}px, ${y - 0}px, 0)`;
    if (!timeout) {
      timeout = setTimeout(function () {
        timeout = null;
        cursor.style.transform = `translate3d(${x - 0}px, ${y - 0}px, 0)`;
      }, 10);

If you look back at my demos you will see the dot follows the cursor quite closely.

However I still think you would be better using a cursor image for the dot and not needing to drag that extra element at all. As you say it may not be an issue when the cursor is turned off so will be a case of test and see :slight_smile:

Unfortunately I am just about to go on holiday for a few weeks and although I will be online from time to time I won’t have access to my trusty mac for testing (just an old PC).

Hope you manage to sort it out anyway :slight_smile:


Thanks so much. I don’t expect you to be checking on your holiday haha. Sorry I’ve been dropping stuff in the thread than disappearing. I’ve been away too the last few weeks. Really appreciate everyones help on this thread!

Both those points are great, just me trying to understand what’s happening rather than copy/paste. Might enable me to actually write code from scratch in the future.

I think everything works great now - will look at integrating it into my ‘live’ theme tomorrow and fingers crossed we have vastly improved performance (might share via DM)! :grin:

Enjoy your holiday @PaulOB - try to stay away from the computer! I did that on my last trip and it did wonders haha

1 Like