Ico no Yuri
Ico no Yuri

Reputation: 11

Why the z-index value does upset the functioning of my animation?

I'm trying recoding the https://www.orizon.co/ following dot. The code I've written to asure the dot rising effect when the pointer fly over some elements seems correct, but when the dot's z-index is higher than the flew over element's one, there is a kind of bug than make me crazy.

class CursorFollower {
    constructor() {
        this.follower = document.getElementById("cursor-follower");
        this.topGap = 12;
        this.leftGap = 4;
        window.addEventListener("mousemove", this.follow.bind(this));
        this.eventsSet();
    }
// The function doing the dot follows the pointer
    follow() {
        setTimeout(function () {
            cursorFollower.follower.style.left = (this.clientX - cursorFollower.topGap) + "px";
            cursorFollower.follower.style.top = (this.clientY - cursorFollower.leftGap) + "px";
        }.bind(window.event), 100);
    }
    eventsSet() {
// Adding events to button
        var button = document.querySelector(".follower-over");
        button.addEventListener("pointerenter", this.overOn.bind(this));
        button.addEventListener("pointerleave", this.overOff.bind(this));
    }
    overOn() {
// The effects to apply when the pointer flies over the button
        this.follower.style.opacity = 0.3;
        this.follower.style.width = "50px";
        this.follower.style.height = "50px";
        this.follower.style.backgroundColor = "black";
        this.topGap = 25;
        this.leftGap = 25;
    }
    overOff() {
// The effects to apply when the pointer leave the button
        this.follower.style.opacity = 1;
        this.follower.style.width = "7px";
        this.follower.style.height = "7px";
        this.follower.style.backgroundColor = "rgba(42, 0, 212, 1)";
        this.topGap = 12;
        this.leftGap = 4;
    }
}
let cursorFollower = new CursorFollower();
/* Some styling */
.contact-us{
    padding: 25px 40px;
    width: 200px;
    display: flex;
    align-items: center;
    color: white;
    background-color: #2b00d4 ;
    height: 60px;
    position: relative;
    z-index: 1;
}
#cursor-follower{
    z-index: 999;
    position: fixed;
    background-color: #2b00d4;
    height: 7px;
    width: 7px;
    border-radius: 50%;
    transition: opacity 0.3s , width 0.3s , height 0.3s, background-color 0.3s;
}
<div id="cursor-follower"></div>
<div class="contact-us follower-over">
  <p>CONTACT US</p>
</div>

When the button's z-index is higher than the dot's one, the effects works. Else, it bugs

Upvotes: 0

Views: 86

Answers (1)

vanowm
vanowm

Reputation: 10201

This is because your follower element is getting under cursor, triggering overOff than when its shrinks it triggers overOn and so on.

The simplest solution is to add pointer-events: none; into the follower so it doesn't trigger overOn/overOff:

class CursorFollower {
  constructor() {
    this.follower = document.getElementById("cursor-follower");
    this.topGap = 12;
    this.leftGap = 4;
    window.addEventListener("mousemove", this.follow.bind(this));
    this.eventsSet();
  }
  // The function doing the dot follows the pointer
  follow() {
    setTimeout(function() {
      cursorFollower.follower.style.left = (this.clientX - cursorFollower.topGap) + "px";
      cursorFollower.follower.style.top = (this.clientY - cursorFollower.leftGap) + "px";
    }.bind(window.event), 100);
  }
  eventsSet() {
    // Adding events to button
    var button = document.querySelector(".follower-over");
    button.addEventListener("pointerenter", this.overOn.bind(this));
    button.addEventListener("pointerleave", this.overOff.bind(this));
  }
  overOn() {
    // The effects to apply when the pointer flies over the button
    this.follower.style.opacity = 0.3;
    this.follower.style.width = "50px";
    this.follower.style.height = "50px";
    this.follower.style.backgroundColor = "black";
    this.topGap = 25;
    this.leftGap = 25;
  }
  overOff() {
    // The effects to apply when the pointer leave the button
    this.follower.style.opacity = 1;
    this.follower.style.width = "7px";
    this.follower.style.height = "7px";
    this.follower.style.backgroundColor = "rgba(42, 0, 212, 1)";
    this.topGap = 12;
    this.leftGap = 4;
  }
}
let cursorFollower = new CursorFollower();
/* Some styling */

.contact-us {
  padding: 25px 40px;
  width: 200px;
  display: flex;
  align-items: center;
  color: white;
  background-color: #2b00d4;
  height: 60px;
  position: relative;
  z-index: 1;
}

#cursor-follower {
  pointer-events: none; /* added */
  z-index: 999;
  position: fixed;
  background-color: #2b00d4;
  height: 7px;
  width: 7px;
  border-radius: 50%;
  transition: opacity 0.3s, width 0.3s, height 0.3s, background-color 0.3s;
}
<div id="cursor-follower"></div>
<div class="contact-us follower-over">
  <p>CONTACT US</p>
</div>

However there is even simpler solution with much less javascript:

window.addEventListener("mousemove", e => {
  setTimeout(s => {
    document.documentElement.style.setProperty("--cursorX", e.clientX + "px");
    document.documentElement.style.setProperty("--cursorY", e.clientY + "px");
  }, 100);
});
/* Some styling */
:root
{
  --cursorX: -100px;
  --cursorY: -100px;
}
.contact-us {
  padding: 25px 40px;
  width: 100px;
  display: flex;
  align-items: center;
  color: white;
  background-color: #2b00d4;
  height: 40px;
  position: relative;
  z-index: 1;
}

.cursor-follower {
  --size: 7px;
  --gapLeft: 12px;
  --gapTop: 4px;
  pointer-events: none;
  position: fixed;
  background-color: #2b00d4;
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  transition: opacity 0.3s, width 0.3s, height 0.3s, background-color 0.3s;
  top: calc(var(--cursorY) - var(--gapTop));
  left: calc(var(--cursorX) - var(--gapLeft));
}

.follower-over:hover~.cursor-follower {
  --size: 50px;
  --gapLeft: 25px;
  --gapTop: 25px;
  opacity: 0.3;
  background-color: black;
  z-index: 2;
}


/* extra */

.follower-over.green:hover~.cursor-follower {
  background-color: green;
  opacity: 0.7;
  --size: 80px;
  --gapLeft: 40px;
  --gapTop: 40px;
}

.contact-us:not(.follower-over) {
  background-color: pink;
}

.contact-us {
  display: inline-block;
  margin: 1em;
}
<div class="contact-us follower-over">
  <p>CONTACT US</p>
</div>
<div class="contact-us follower-over">
  <p>Another button</p>
</div>
<div class="contact-us">
  <p>No follower</p>
</div>
<div class="contact-us follower-over green">
  <p>Large green</p>
</div>

<div class="cursor-follower"></div>

The only caveat with this method is the .cursor-follower must be last element and has the same parent as all .follower-over elements

Upvotes: 1

Related Questions