circusfox
circusfox

Reputation: 11

How to change cursor on multiple mouseovers

I am trying to change my cursor into different images depending on the object that it is hovering over inside my banner. Currently I only know to change the cursor style in CSS. But the cursor stays the same throughout. How do I replace the cursor image on mouseover in my javascript? I am only using jQuery and TweenMax as this is for an assignment.

Upvotes: 1

Views: 859

Answers (1)

Ivan
Ivan

Reputation: 40638

Using CSS cursor property

Without using any pseudo-selectors in CSS, you can have a pretty good result by playing around with the cursor property. For example, you can select one cursor style from a range of available ones. Or even add your own by linking the URL of the icon.

For example, the code below will show a heart when you hover over the grey area:

.heart {
  cursor: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9632/heart.png"), auto;
  width: 200px;
  height: 200px;
  background: grey;
}
<div class="heart"></div>

You can change the origin of the image's position relative to the actual mouse position by setting the x and y position along with the URL in the cursor property:

cursor: url(<URL>) [x y|auto];

Using JavaScript

Of course, you can handle this feature with JavaScript code. Here are several things we will need to achieve this:

  • creating an HTML element with the image of the cursor you want as background

  • using the onmouseenter, onmousemove and onmouseleave events

  • getting the position of the mouse on the page: properties pageX, pageY

  • setting the position of our cursor element to be at the position of the mouse (the actual mouse pointer will be hidden): with the transform CSS property.

There are several other tricks I have used to get it right: for example setting the boxes' overflow to be hidden so that the cursor elements can't be seen outside the box. Also, listening to the onmouseleave event allows us to hide the cursor element when the mouse is outside the box area.

I have made a little demo here, click Show code snippet > Run code snippet:

const showCursor = function(event) {
  let cursor = event.target.querySelector('.cursor');
  
  event.target.onmousemove = function(e) {
    cursor.style.display = 'block'
    let [x, y] = [e.pageX - e.target.offsetLeft - 20, e.pageY - e.target.offsetTop - 20]
    cursor.style.transform = `translate(${x}px, ${y}px)`
  }

  event.target.onmouseleave = function(e) {
    cursor.style.display = 'none'
  }

}
.box {
  cursor: none;
  overflow: hidden;
  width: 200px;
  height: 200px;
  background: pink;
  display: inline-block;
  margin: 10px;
}

.box:nth-child(1) {
  background: aquamarine;
}

.box:nth-child(2) {
  background: pink;
}

.box:nth-child(3) {
  background: cornflowerblue;
}

.box:nth-child(4) {
  background: lightcoral;
}

.cursor {
  display: none;
  width: 100px;
  height: 100px;
}

#heart {
  background: no-repeat url("https://png.icons8.com/color/50/000000/hearts.png");
}

#diamond {
  background: no-repeat url("https://png.icons8.com/color/50/000000/diamonds.png")
}

#spade {
  background: no-repeat url("https://png.icons8.com/metro/50/000000/spades.png")
}

#clubs {
  background: no-repeat url("https://png.icons8.com/ios/50/000000/clubs-filled.png")
}
<div onmousemove="showCursor(event)" class="box">
  <div id="diamond" class="cursor"></div>
</div>
<div onmouseenter="showCursor(event)" class="box">
  <div id="heart" class="cursor"></div>
</div>

<div onmousemove="showCursor(event)" class="box">
  <div id="spade" class="cursor"></div>
</div>
<div onmousemove="showCursor(event)" class="box">
  <div id="clubs" class="cursor"></div>
</div>

The function showCursor() is called when the user's mouse enters one of the boxes with the attribute onmouseenter="showCursor(event)" (see HTML markup above).

Below I have provided the JavaScript code with comments explaining how it works:

const showCursor = function(event) {
  // get the element object of the cursor of this box
  let cursor = event.target.querySelector('.cursor');

  // function that will be execute whenever the user moves inside the box
  event.target.onmousemove = function(e) {
    // the user is moving inside the box

    // show the cursor element
    cursor.style.display = 'block'

    // calcultate the translate values of the cursor element
    let [x, y] = [e.pageX - e.target.offsetLeft - 20, e.pageY - e.target.offsetTop - 20]

    // apply these values to the style of the cursor element
    cursor.style.transform = `translate(${x}px, ${y}px)`

  }

  // function that will be executed when the user leaves the box 
  event.target.onmouseleave = function(e) {
    // the user's mouse left the box area

    // hide the cursor element
    cursor.style.display = 'none'
  }

}

With a <svg> element

A while ago I answered a post on how to add an <svg> element as the cursor of the mouse. It's a little bit more advanced though. It's still a JavaScript solution but it involves using a <svg> element as the cursor instead of it being a simple <div> (as seen in the second point).

Upvotes: 2

Related Questions