score:0

the flickering is due to two reasons:

  1. creating a new image in each drawing is an expensive operation, so it is best to use a reference, that has brought me a lot of optimization
  2. the change in size can be felt somewhat abrupt, especially if it is done with the mouse wheel. so the best is to use requestanimationframe.

if you only perform step 1 there will be no flickering.

the code would look like this:

  const canvasref = useref(null);
  const requestref = useref();
  const image = useref(null);
  const [cargoheight, setcargoheight] = usestate(100);
  const [cargowidth, setcargowidth] = usestate(100);

  const draw = () => {
    const canvas = canvasref.current;
    const img = new image();
    const ctx = canvas.getcontext("2d");
    canvas.width = image.current.width;
    canvas.height = image.current.height;
    ctx.drawimage(
      image.current,
      0,
      0,
      image.current.width,
      image.current.width
    );
  };

  uselayouteffect(() => {
    requestref.current = requestanimationframe(draw);
    return () => window.cancelanimationframe(requestref.current);
  }, [cargoheight, cargowidth]);

  return (
    <div classname="app">
      <img
        src={
          "https://www.tuexperto.com/wp-content/uploads/2020/01/png.jpg.webp"
        }
        ref={image}
        style={{ display: "none" }}
      />
      <cargo ref={canvasref} height={cargoheight} width={cargowidth} />
      <button onclick={() => setcargoheight(cargoheight + 50)}>height</button>
      <button onclick={() => setcargowidth(cargowidth + 50)}>width</button>
    </div>
  );

a codesandbox with the solution and the complete example


Related Query

More Query from same tag