Angular: follow cursor has too much delay/lag

Viewed 40

I wanted to try to do the angular version of a cursor follow movement, but the mouse movement is not smooth, how do I fix this and what's the reason for it?: https://stackoverflow.com/a/48756322/5152892

My angular attempt: https://stackblitz.com/edit/angular-vnx9yd?file=src/app/app.component.ts

export class AppComponent {
  name = 'Angular';

  constructor(
    private el: ElementRef
  ) {}

  get tooltip() {
    return this.el.nativeElement.querySelector('.sites-circle');
  }

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

  move(e: { pageX: number; pageY: number }) {
    const tooltipStyle = this.tooltip.style;

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

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

CSS:

p {
  font-family: Lato;
}

.mouse-circle {
  position: absolute;
  border: solid 1px #ccc;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: white;
}
.show {
  opacity: 1 !important;
}

.sites-circle {
  z-index: 500;

  position: absolute;
  border: solid 1px #ccc;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: blue;
  pointer-events: none;
  transition-duration: 200ms;
  transition-timing-function: ease-out;
  transform: translate(-50%, -50%);
  opacity: 0;
}

.wrapper {
  height: 100vh;
  width: 100%;
}

HTML:

<div
  class="wrapper"
  (mouseenter)="enter()"
  (mousemove)="move($event)"
  (mouseleave)="leave()"
>
  <p>Start editing to see some magic happen :)</p>
  <div class="sites-circle">hello</div>
</div>
1 Answers

sometimes is better use fromEvent rxjs operator to mannage mousemove. This allow use different operators to not emit constantly the event

Use Viewchild to get the elements

<div #mydiv class="show"
  class="wrapper"
  (mouseenter)="enter()"
  (mouseleave)="leave()"
>
  <div #tooltip class="sites-circle">hello</div>
</div>

@ViewChild('mydiv',{static:true}) div:ElementRef
@ViewChild('tooltip',{static:true}) tooltipEl:ElementRef

Then

  ngOnInit()
  {
    this.subscription=fromEvent(this.div.nativeElement,'mousemove').pipe(
        throttleTime(200,asyncScheduler,{ trailing: true }))
          .subscribe((e:any)=>{
             const tooltipStyle = this.tooltip.style;

             tooltipStyle.left = e.pageX + 'px';
             tooltipStyle.top = e.pageY + 'px';
             this.cont++;
    })
  }
  ngOnDestroy()
  {
    this.subscription.unsubscribe()
  }

In the e.g. (see stackblitz) I use throttleTime to not emit a new event until 200 miliseconds (you can change to 100 or 150)

Related