扩展 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 中进行一些调试后,我将问题缩小为 sizeScalingFactor
在 resize()
被调用时 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).
我一直在编写一个 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 中进行一些调试后,我将问题缩小为 sizeScalingFactor
在 resize()
被调用时 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).