#Canvas API

It is a low-level, but useful API. To render something, you can choose different contexts, like 2d for example. This gives you a flexibility for using any rendering methods supported by your browser including WebGL.

When composed with React.js, you usually want to wrap it in an useEffect hook.

#Dynamic Size

It is also possible to adjust the size of canvas dynamically. Be careful of the pixel ratio, it may impact the quality of rendering.

In general, canvas.width does not equal to canvas.clientWidth. Instead, canvas.width is the size of your drawing. After the image being rendered, the rendered image will be scaled to the client size. It can be problematic when the drawing size is lower than its client size, sometimes resulting in a "blurry" resolution image.

You should multiply the drawing size with user's pixel ratio, so that it can look sharper.

"use client";
import { useRef, useEffect } from "react";

export function Canvas() {
  const ref = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const ctx = element.getContext("2d")!;
    const width = element.clientWidth,
      height = element.clientHeight;

    // set width and height dynamically
    element.width = width * window.devicePixelRatio;
    element.height = height * window.devicePixelRatio;
    ctx.scale(window.devicePixelRatio, window.devicePixelRatio);

    // draw something
  }, []);

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

#Animation

To render an animation smoothly, you can utilize the requestAnimationFrame function. It is guaranteed to be fired every frame, and is interupted automatically when user leaves the page.

Remember to stop it when the component is unmounted.

useEffect(() => {
  let unmounted = false;

  function render() {
    if (unmounted) return;

    // draw something
    requestAnimationFrame(() => render());
  }

  return () => {
    unmounted = true;
  };
}, []);

#WebGL

Sometimes we do want a more powerful, performant rendering method, and WebGL might be the best opinion. As named, it's the Web version of OpenGL. You can write shaders in GLSL (a programming language similar to C) and compile them in runtime. It is very effective, especially for GPU accelerated animations that involves heavy calculations.

But it can be pretty difficult for beginners, and configuring it correctly takes patience. I prefer using Phenomenon as a wrapper for WebGL, it saves a lot of time.

#Art and Passion

This is the most enjoyable piece of Web Design. You have a powerful, comprehensive set of tools and infinite possibilities to design something. Hope this post can inspire you to create something cool!

Last Updated: