0

I have an element following my mouse around the page on mousemove. It works fine but when I scroll the page, the mouse does not follow, how do I fix it so that it follows it on scroll?

https://stackblitz.com/edit/angular-lg2p6f?file=src/app/app.component.html

HTML:

<div
  class="wrapper"
  (mouseenter)="enter()"
  (mousemove)="move($event)"
  (mouseleave)="leave()"
>
  <p>Start editing to see some magic happen :)</p>
  <div class="sites-circle" [ngClass]="mouseMove ? 'onMove' : 'notMove'">
    hello
  </div>
</div>

TS:

  enter(source: string) {
    this.tooltip.classList.add('show');
  }

  mouseStopped() {
    this.mouseMove = false;
    console.log("mousemove: " + this.mouseMove);
  }

  move(e: { pageX: number; pageY: number }) {

    this.mouseMove = true;
    console.log("mousemove: " + this.mouseMove);

    var timer;
    clearTimeout(timer);
    timer = setTimeout(this.mouseStopped, 300);

    const tooltipStyle = this.tooltip.style;

    tooltipStyle.left = e.pageX + 'px';
    tooltipStyle.top = e.pageY + 'px';
  }

  leave() {
    this.tooltip.classList.remove('show');
  }

CSS:

.sites-circle.onMove {
  transform: scale(3);
}
.sites-circle.notMove {
  transform: scale(1) !important;
}
Snorlax
  • 4,425
  • 8
  • 37
  • 68
  • Can try :- Add mouse events on documents than div. [Please see this link for more details](https://medium.com/claritydesignsystem/four-ways-of-listening-to-dom-events-in-angular-part-3-renderer2-listen-14c6fe052b59) – Pradeep Kumar Oct 18 '22 at 18:41
  • [is this help?](https://stackoverflow.com/questions/16529807/mousemove-event-is-triggered-onscroll-even-when-mouse-was-not-moved-on-chrome)? – Pradeep Kumar Oct 18 '22 at 18:42
  • [Add scroll event and write some logic here](https://stackoverflow.com/questions/45977888/onscroll-event-triggers-function-in-angular4) might work – Pradeep Kumar Oct 18 '22 at 18:57

1 Answers1

1

According to this answer, we cannot get mouse current position on scroll we can just get how much it scrolled relative to last position.

For your problem, this can be realized as follows (here is your updated stackblitz):

  1. Add a (window:scroll) listener to your <div>.
<div
  class="wrapper"
  (mouseenter)="enter()"
  (mousemove)="move($event)"
  (window:scroll)="onScroll($event)"
  (mouseleave)="leave()"
>
  1. Hold the last position, e.g.:
lastPosition = {
    x: undefined,
    y: undefined,
};

...

// inside your move() function
this.lastPosition.x = e.pageX;
this.lastPosition.y = e.pageY;
  1. Hold the last known "move" page offset:
lastMovePageOffset = {
    x: undefined,
    y: undefined,
};

...

// inside your move() function
this.lastMovePageOffset.y = window.pageYOffset;
  1. Use the difference of the current scroll position and the last known page "move" page offset to calculate the new position:
onScroll(e: any) {
    if (this.lastPosition.y !== undefined) {
      let pageOffsetY = 0;
      if (this.lastMovePageOffset.y !== undefined) {
        pageOffsetY = window.pageYOffset - this.lastMovePageOffset.y;
      }
      this.tooltip.style.top = this.lastPosition.y + pageOffsetY + 'px';
    }
}

This can be handled similarly with the x-Position. The solution works as soon as the cursor is moved once before scrolling (caused by the general problem described in the first sentence).

Good luck!

Tommy
  • 2,355
  • 1
  • 19
  • 48
  • this makes sense but I added some more paragraphs, and it looks like the behavior becomes erratic, the element doesn't follow the mouse when scrolling up at all, and when I start scrolling down, the element becomes behaving strange. Is it the same for you?: https://stackblitz.com/edit/angular-bmwktc?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.css – Snorlax Oct 19 '22 at 02:58
  • This was indeed a problem! I just edited my answer to take into account the last known move page offset (and also updated the [stackblitz](https://stackblitz.com/edit/angular-tu8vho?file=src/app/app.component.ts)). Please have a look at it. – Tommy Oct 19 '22 at 14:42
  • 1
    Ah I see what you did, thanks! – Snorlax Oct 20 '22 at 00:23