扩展 p5 class 时未定义 属性

Undefined property when extending p5 class

我一直在编写一个 p5js 应用程序,最近我转而使用 React。调整项目后,一切似乎都在 Firefox 中正常工作,但是当我尝试在 Chrome 中测试它时,canvas 没有被赋予正确的宽度和高度,但是 NaN相反。

我正在使用以下代码扩展 p5 class:

export class CustomCanvas extends p5 {
    sizeScalingFactor = 0.9;

    resize() {
        const canvasSize = this.calculateSize();
        this.resizeCanvas(canvasSize, canvasSize);
    }

    get boundingRect() {
        return this.canvas.getBoundingClientRect();
    }

    calculateSize() {
        return (
            Math.min(
                this.windowWidth,
                this.windowHeight - this.boundingRect.top
            ) * this.sizeScalingFactor
        );
    }
}

在 Chrome DevTools 中进行一些调试后,我将问题缩小为 sizeScalingFactorresize() 被调用时 undefined,使得 calculateResize() return NaN。然而,这根本没有意义,因为构造函数应该是第一个被调用的东西,定义 属性,然后是任何其他方法。

我还检查了 create-react-app 生成的代码,属性 定义被转换为:

constructor(...args) {
    super(...args);
    this.sizeScalingFactor = 0.9;
}

但是,我自己执行此操作并在 Chrome DevTools 中再次调试,导致 resize() 在构造函数之前再次被调用。

我有更多 class 属性以这种方式定义,none 有这个问题,在 Chrome 和 Firefox 中都没有。另外,我应该补充一点,如果我将 属性 设置为静态(然后直接从 class 访问它)或者我将它放在外部范围内,则该项目在没有反应的情况下运行完美,并且一切正常。

我将附上一些可能相关的代码。

实例模式的草图定义:

import { generateGradientArray } from "./palette-manager";
import { CustomCanvas, Circle } from "./classes";

export function createSketch(maxNodeCount, ref) {
    /*
     * @param {CustomCanvas} c
     */
    function sketch(c) {
        const lineColors = generateGradientArray(
            c,
            maxNodeCount,
            //["#B9E3C6", "#59C9A5", "#D81E5B", "#23395B", "#FFFD98"]
            ["#AFCBFF", "#254441", "#43AA8B", "#B2B09B", "#EF3054"]
        );

        const circle = new Circle(c, lineColors);

        function resizeComponents() {
            c.resize();
            circle.resize();
        }

        c.setup = () => {
            resizeComponents();
        };

        c.draw = () => {
            c.clear();
            c.translate(c.width / 2, c.height / 2);
            c.scale(1, -1);

            circle.draw();
        };

        c.windowResized = () => {
            resizeComponents();
        };
    }

    return new CustomCanvas(sketch, ref);
}

草图组件:

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

import style from "./Sketch.module.css";
import { createSketch } from "../sketch";

export default function Sketch() {
    const containerRef = useRef();

    useEffect(() => {
        const sketch = createSketch(700, containerRef.current);

        return () => {
            sketch.remove();
        };
    }, []);

    return <div ref={containerRef} className={style.container}></div>;
}

知道为什么会这样吗?提前致谢。

问题在于,在某些浏览器中,对 p5 构造函数的调用在此上下文中立即触发对 this.resize() 的调用,而在其他浏览器中,对构造函数 returns 的调用然后在事件处理程序中调用 this.resize()。区别在于调用构造函数时 document.readyState 是否等于 'complete'。您可以在生成的代码中看到为什么会出现问题:

    constructor(...args) {
        super(...args); // calls this.resize();
        this.sizeScalingFactor = 0.9;
    }

    resize() {
        // When this is called from the base class constructor
        // sizeScalingFactory is still undefined
    }

这里是 sample code on replit.com (or check out the running version).