What steps can be taken to ensure that the requestAnimationFrame function does not redraw the canvas multiple times after a button click?

I am currently working on a project where I am drawing a sin wave on a canvas and adding movement to it.

export class CanvasComponent implements OnInit {
  @ViewChild('canvas', { static: true })
  canvas: ElementRef<HTMLCanvasElement>;

  ctx: CanvasRenderingContext2D;

  winddrawvalue = 0;
  windvalue = 0;

  constructor() { }

  @Input() set speeddata(speed: number){
    this.windvalue = speed;
    this.drawWind();
  }

  ngOnInit(): void {
    this.ctx = this.canvas.nativeElement.getContext('2d');
  }

  drawWind() {
    requestAnimationFrame(this.drawWind.bind(this));
    const canvas = this.canvas.nativeElement;
    this.ctx.lineWidth = 2;
    this.ctx.clearRect(0, 0, canvas.width, canvas.height);
    this.ctx.beginPath();

    this.ctx.moveTo(-10, canvas.height / 2 - 12);
    for (let i = 0; i < canvas.width; i++) {
      this.ctx.lineTo(i, canvas.height / 2 - 12 + Math.sin(i * 0.04 + this.winddrawvalue) * 15);
    }

    this.ctx.moveTo(-10, canvas.height / 2);
    for (let i = 0; i < canvas.width; i++) {
      this.ctx.lineTo(i, canvas.height / 2 + Math.sin(i * 0.04 + this.winddrawvalue) * 15);
    }

    this.ctx.moveTo(-10, canvas.height / 2 + 12);
    for (let i = 0; i < canvas.width; i++) {
      this.ctx.lineTo(i, canvas.height / 2 + 12 + Math.sin(i * 0.04 + this.winddrawvalue) * 15);
    }

    this.ctx.stroke();
    this.winddrawvalue += this.windvalue;
  }

}

Every time I press the button to redraw the canvas, it moves at double the speed of before. In an attempt to fix this issue, I tried:

request = requestAnimationFrame(this.drawWind.bind(this));

  @Input() set speeddata(speed: number){
    this.windvalue = speed;
    this.stopAnimation(this.request);
    this.drawWind();
  }

  stopAnimation(req) {
    cancelAnimationFrame(req);
  }

I used cancelAnimationFrame() with hopes that it would retrieve the requestID to stop the ongoing animation, but unfortunately, it did not work as expected.

Answer №1

When calling drawWind, it's setting up the next call every time, which results in having two series running at once when called from the click handler, making things speed up.

You mentioned attempting to use cancelAnimationFrame but didn't provide the code for it. Here is how you should handle it:

drawWind() {
  cancelAnimationFrame(this.animationFrameHandle);
  this.animationFrameHandle = requestAnimationFrame(this.drawWind.bind(this));

By implementing this, when the button click triggers drawWind while an rAF callback is already scheduled, it cancels that callback and sets a new one. This ensures that only one series is running at any given time.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Intermittent issue with Angular 2 encountered while following the Hero Editor tutorial on angular.io

I am encountering an occasional error in the console while following the angular.io tutorial using Mozilla Firefox. The error does not seem to impact the functionality or rendering of my application, and it only happens sporadically. If you could provide ...

Mastering error handling in Angular's Http requests

In my frontend application using Angular, I need to communicate with a RESTful webservice for the login process. The webservice returns different response codes in JSON format depending on the success or failure of the login attempt: If the login is corre ...

Discriminator-based deserializer with strong typing

Seeking advice on how to effectively utilize TypeScript for strongly typing a function that operates similarly to the following example: function createDeserializer(typeDeserializers) { return (data) => { const deserializer = typeDeserializ ...

Facing problem with Angular 7 when making a GET request for non-JSON data

Currently, I am retrieving JSON data from a URL using the following method: this.http.get('http://localhost:3200/mydata').subscribe(data => { console.log(data); }); The response is in JSON format, and everything seems to be working fine. ...

Utilizing TypeScript for enhanced Chrome notifications

I am currently developing a Chrome app using TypeScript (Angular2) and I want to implement push notifications. Here is the code snippet for my notification service: import {Injectable} from 'angular2/core'; @Injectable() export class Notificati ...

What could be causing the errors I'm encountering in my TypeScript component within AngularJS?

I am working with an AngularJS component written in TypeScript called news.component.ts. This component makes a call to a service named google.service.ts in order to fetch news RSS using a service that converts XML to JSON. Within the NewsComponent, I hav ...

What is the best way to send an action based on the HTTP method being used?

I've been utilizing NGXS for handling state in my angular project. What would be considered a best practice? Should I make the HTTP call first and then dispatch an action within its subscription? Or should I dispatch the action first and then make t ...

Tips for implementing <mat-progress-bar> in .ts file when making API service requests with Angular

I'm currently utilizing an API call to retrieve an image from a service, and I would like to display a progress bar while the image is being fetched. It seems that I need to incorporate the progress bar within the service as the image data is returned ...

The current directory does not belong to a Cordova project

Upon executing ionic cordova run browser --verbose within the main directory of my Ionic4 project, I encounter the error message "Current working directory is not a Cordova-based project." as shown below. I've observed that the command generates a "w ...

Using Angular to make an HTTP POST request to fetch data

My trusty .net backpack has been working flawlessly. However, I encountered an issue when trying to connect it with the Angular front end. All backend requests are post requests and require passing an ApiKey in the body of each request. Interestingly, ever ...

Utilizing Input Values in Angular Components - A Step-by-Step Guide

I am a beginner in Angular and attempting to build a basic todo application. I have utilized [(ngModel)] to send the input value to the component, but it seems that I am doing it incorrectly. Below is my code: HTML: <div class="todo-app"> <h ...

NGRX effect in Nativescript Angular loses state when the app is suspended on iOS

While using NGRX with Nativescript Angular to manage state and fetch data from the server, I've encountered an issue when suspending the app on IOS. Whenever the app is in the middle of fetching data from the server and gets suspended, the entire proc ...

What steps should I take to resolve the ChunkLoadError related to signalr?

Recently, I encountered an issue while running my nx site locally. It seems that any federated app using signalR is now throwing a ChunkLoadError. I attempted various solutions such as changing the version of signalR, reloading the page, clearing cache, a ...

Expanding the npm packages available on the Azure DevOps Feed

My current project utilizes Angular 2.4 and includes a .npmrc file configured to use an internal registry. The build pipeline I have set up is throwing the following error: No matching version found for yargs@^3.32.0. In most cases you or one of your dep ...

The dropdown navigation bar fails to close upon being clicked

I'm currently facing an issue with the navbar in my project. The bootstrap navbar doesn't close automatically after clicking on a link. I have to move my mouse away from the navbar for it to close, which is not ideal. Additionally, I'm worki ...

Using the hook to implement the useContext function in React

I came across this definition export interface user{ email:string name:string last_name:string } export type UserType= { user: user; setUser:(user:user) => void; } const [user,setUser] = useState <user> ({ email ...

Consecutive API requests within React context

When I'm developing locally, I encounter the error message Error: Rendered more hooks than during the previous render. in my application when refreshing the page. I suspect this is happening because I am making two calls within my provider. The first ...

Ways to retrieve the identifier of a specific element within an array

After successfully retrieving an array of items from my database using PHP as the backend language, I managed to display them correctly in my Ionic view. However, when I attempted to log the id of each item in order to use it for other tasks, it consistent ...

Is there a way to incorporate timeouts when waiting for a response in Axios using Typescript?

Can someone assist me in adjusting my approach to waiting for an axios response? I'm currently sending a request to a WebService and need to wait for the response before capturing the return and calling another method. I attempted to utilize async/aw ...

I am unable to refresh the table data in Angular

Here is the code that I am currently working with: I am facing an issue where my webpage is not updating its data after performing delete or any other operations. The user list is not being displayed in the data. Despite my attempts, I have been unable to ...