LePhenix47 / Audio-Visualizer_Younes-Lahouiti

This is a JavaScript audio visualizer that uses HTML5 `<canvas>` elements to create stunning visual representations of audio waveforms
https://lephenix47.github.io/Audio-Visualizer_Younes-Lahouiti/
1 stars 0 forks source link

[CONCEPT] Basic fundamentals of the `<canvas>` #4

Open LePhenix47 opened 1 year ago

LePhenix47 commented 1 year ago

What's a <canvas>?

It's an HTML element used along with the Canvas JS API to draw animations or 2D/3D graphics

We can have access to these methods after selecting the <canvas> and getting it's context

Let's make an example:

<canvas></canvas>
canvas{
   position: absolute;

   width: 100%;
   height: 100%;
}
const canvas= document.querySelector("canvas");
const canvasContext = canvas.getContext("2d"); //Also possible to have "webgl" as a value
LePhenix47 commented 1 year ago

How to set a width for the canvas (JS + React)

Once we have selected the element and obtained its context, it is important to define a fixed height and width for it However, these dimensions need to be dynamically adjusted to accommodate changes in the window size: Vanilla JS:

//We set the width and height of the raster of the canvas
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

/**
 * Handles the window resize event by adjusting the canvas raster accordingly.
 * @returns {void}
 */
function handleWindowResize(): void {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

//We resize the canvas whenever the user resizes the window of the browser
window.addEventListener("resize", handleWindowResize);

React:

import React, { useEffect, useRef } from 'react';

/**
 * CanvasComponent.
 * @returns {JSX.Element} Canvas component.
 */
function CanvasComponent(): JSX.Element {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas: HTMLCanvasElement = canvasRef.current;
    const context: CanvasRenderingContext2D = canvas?.getContext('2d');

    /**
     * Handles the window resize event by adjusting the canvas dimensions accordingly.
     * @returns {void}
     */
    function handleWindowResize(): void {
      if (canvas) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        // Perform any additional drawing or logic based on the resized dimensions
      }
    }

    handleWindowResize(); // Set initial dimensions on component mount

    window.addEventListener('resize', handleWindowResize);

    // Clean up the event listener on component unmount
    return () => {
      window.removeEventListener('resize', handleWindowResize);
    };
  }, []);

  return <canvas ref={canvasRef} />;
}

export default CanvasComponent;
LePhenix47 commented 1 year ago

Animate the canvas

To ensure a clean canvas for each frame and create a continuous animation loop, we can implement the animate() function. This function will utilize the clearRect() method to clear the canvas element, and recursively invoke the requestAnimationFrame function. It's important to remember to call our animate() function to initiate the animation loop:

function animate() {
  // Clear the entire canvas
  canvasContext.clearRect(0, 0, canvas.width, canvas.height);

  // Call functions or methods to create effects in the canvas here

  // Create a loop
  requestAnimationFrame(animate);
}

t's worth mentioning that the frames per second (FPS) can also be adjusted by using the setTimeout() function.

Furthermore, when working with elements, object-oriented programming (OOP) is commonly utilized instead of functional programming (FP).

LePhenix47 commented 1 year ago

Coordinates system

The canvas adopts the same coordinate system as SVG, with the origin positioned at the top left corner

image

LePhenix47 commented 1 year ago

CodePen examples (non-interactive):

Moving particles n°1

https://codepen.io/phenix47/pen/poxRmNm

Matrix rain effect

https://codepen.io/phenix47/pen/KKGqpOY?editors=0110

Bouncing particles

https://codepen.io/phenix47/pen/XWxzKOW

Moving particles n°2

https://codepen.io/phenix47/pen/OJBzOQp