Search code examples
javascriptreactjscanvasp5.js

How to resize a canvas properly in React using p5js?


I'm currently working on a project and one part is about resizing the model in the canvas once the canvas is resized (or window is resized). I have checked documentation for resizeCanvas() and applied it.

I'm first finding the ratio by dividing the currentWidth/defaultWidth which are currentWidth of the user's device and the default/selected width by us, respectively.

  findRatio(wd, hd, wc, hc) {
    const w = wc / wd;
    const h = hc / hd;
    return w < h ? w : h;
  }

and in my windowResized() function, I'm setting width/height once canvas is resized on window resize.

export const windowResized = (p5) => {
  if (p5) {
    initVariables.browserWidth = p5.windowWidth;
    initVariables.browserHeight = p5.windowHeight;
    p5.resizeCanvas(initVariables.browserWidth, initVariables.browserHeight);
    for (let m of initVariables.mM) {
      m.updateonResize();
    }
  }
};

here initVariables is just an object with some bunch of variables.

I also have updateonResize() function in my parent class that triggers once window is resized.

 updateonResize() {
    this.r = this.findRatio(
      this.initVariables.width,
      this.initVariables.height,
      this.initVariables.browserWidth,
      this.initVariables.browserHeight
    );
    this.arr.push(this.r);

    if (this.arr[this.arr.length - 2] !== undefined) {
      if (this.r < this.arr[this.arr.length - 2]) {
        console.log("canvas getting larger, not sure if I need to divide or multiply here");
        this.min = this.min * this.r;
        this.max = this.max * this.r;
        this.measure = this.measure * this.r;
      } else {
        this.min = this.min * this.r;
        this.max = this.max * this.r;
        this.measure = this.measure * this.r;
      }
    }
  }

Here, min, max, and measure variables are variables to detect the size of object parts which are the length of lines. If the canvas is getting smaller, you need to multiply measure value with ratio (where ratio is usually less than 1).

Problem1: I'm having a problem when I go to window mode from full-screen mode in my Chrome browser. It does not trigger the windowOnResize() function. Is it possible to automatically trigger this function once you go to window mode?

Problem2: When you resize the browser, the ratio changes every frame, and thus measure*ratio value becomes too low (to 0). Is there any algorithm I could apply to decrease the measure value slightly, but not drastically?


Solution

  • I have found the solution myself. I have added resize event listener with JavaScript and find the ratio with my own function and resize the canvas with it. I have added timeout not to see changes at the same time, but after some delay.

    let timeOutFunctionId;
    
    window.addEventListener("resize", function () {
      if (!initVariables.subSet) {
        r = findRatio(
          initVariables.width,
          initVariables.height,
          initVariables.browserWidth,
          initVariables.browserHeight
        );
        clearTimeout(timeOutFunctionId);
        timeOutFunctionId = setTimeout(() => {
          if (p5) {
            if (true) {
              initVariables.browserWidth = p5.windowWidth - 310;
              initVariables.browserHeight = p5.windowHeight - 200;
            } else {
            }
            p5.resizeCanvas(
              initVariables.browserWidth,
              initVariables.browserHeight
            );
            //calling custom class 
          }
        }, 500);
      }
    });