You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用P5-wrapper/react的WEBGL模式重复创建Canvas问题求助

问题描述

我在使用P5-wrapper/react展示自定义2D模型时遇到问题:每当React状态变更,Canvas就会被反复创建,同时出现警告WARNING: Too many active WebGL contexts. Oldest context will be lost.。

我整理了简化后的相关代码信息:

Measurement类定义

用于创建特定测量对象:

class Measurement {
  constructor(p5, initVariables, onChangeDraw, _ref) {
    this.p5 = p5;
    this.initVariables = initVariables;
    this.onChangeDraw = onChangeDraw;
    this.ref = _ref;
    this.pointActive = false;
    this.activePoint = this.p5.createVector(0, 0);
  }

  checkPoints() {
    if (
      this.p5.dist(
        this.p5.mouseX,
        this.p5.mouseY,
        this.ref.x + 300,
        this.ref.y + 250
      ) < 26
    ) {
      this.activePoint = this.ref.x;
      this.pointActive = true;

      if (this.initVariables.mP) {
        this.ref.x = this.p5.mouseX - 300;
        this.ref.y = this.p5.mouseY - 250;
      }
    } else {
      this.pointActive = false;
    }

    if (this.initVariables.mP && this.onChangeDraw && this.pointActive) {
      this.onChangeDraw();
    }
  }

  drawMeasurement() {
    if (this.pointActive) {
      this.p5.noStroke();
      this.p5.fill(0, 20);
      this.p5.circle(this.ref.x, this.ref.y, 13);
    }
    this.p5.stroke(255, 0, 0);
    this.p5.fill(255, 0, 0);
    this.p5.strokeWeight(2);
    this.p5.circle(this.ref.x, this.ref.y, 5);
    this.p5.noFill();
  }
}

全局变量与函数

const mM = [];
let dataDimensions = [];
let setDataDimensions;

let initVariables = {
  mP: false,
};

const onChangeDraw = () => {
  setDataDimensions([...dataDimensions]);
};

Sketch函数实现

const sketch = (p5, measurements, setMeasurements) => {
  p5.setup = () => {
        measurements.map((measurement) => {
      const name = new Measurement(
        p5,
        initVariables,
        onChangeDraw,
        measurement.ref
      );
      mM.push(name);
    });
    dataDimensions = measurements;
    setDataDimensions = setMeasurements;
    p5.createCanvas(600, 500, p5.WEBGL);
  };

  p5.draw = () => {
    p5.background(237, 239, 237);
    p5.stroke(0);
    p5.strokeWeight(2);
    p5.circle();
    p5.beginShape();

    for (let m of mM) {
      m.drawMeasurement();
      m.checkPoints();
    }

    mM.map((measurement) => p5.vertex(measurement.ref.x, measurement.ref.y));
    p5.endShape(p5.CLOSE);
  };

  p5.mousePressed = () => {
    initVariables.mP = true;
  };
  p5.mouseReleased = async () => {
    initVariables.mP = false;
  };
};

React状态定义

const [measurements, setMeasurements] = useState([
    {
      id: 1,
      ref: {
        x: 100,
        y: 100,
      },
    },
    {
      id: 2,
      ref: {
        x: 200,
        y: 100,
      },
    },
    {
      id: 3,
      ref: {
        x: 200,
        y: 200,
      },
    },
    {
      id: 4,
      ref: {
        x: 100,
        y: 200,
      },
    },
  ]);

组件Wrapper代码

<div className="App">
      <ReactP5Wrapper
        sketch={(p5) => sketch(p5, measurements, setMeasurements)}
      />
    </div>

问题触发场景

当点击并拖拽任意点时,onChangeDraw会更新React状态,此时Canvas会被重复创建,触发上述警告。

内容的提问来源于stack exchange,提问作者mrconcerned

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 23:37:34