I'm having a problem with my code where I am using P5-wrapper/react to show the 2D model I created. However, whenever React states changes it re-creates the canvas again and again it gives warning that WARNING: Too many active WebGL contexts. Oldest context will be lost.
.
My code is a bit complex, thus I have created a simple example in this codesandbox, but I will also give a bit information.
I got Measurement
class where I am using to set up specific measurement objects.
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();
}
}
and some variables and function:
const mM = [];
let dataDimensions = [];
let setDataDimensions;
let initVariables = {
mP: false,
};
const onChangeDraw = () => {
setDataDimensions([...dataDimensions]);
};
and I have this sketch
function I am using:
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;
};
};
problem seems to be once I click and drag any point where state changes because of onChangeDraw
where I set the measurements into new measurements I get from p5
side.
So, also including measurements for reference:
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,
},
},
]);
and wrapper:
<div className="App">
<ReactP5Wrapper
sketch={(p5) => sketch(p5, measurements, setMeasurements)}
/>
</div>
The solution was rather simple that I imagined. I had to use updateWithProps
which is mentioned in Wrapper.
So, it could be like:
<ReactP5Wrapper sketch={sketch} measurements={dimensions} setMeasurements={setDimensions} />
and
const sketch = (p5) => {}
p5.updateWithProps = props => {
dataDimensions = props.measurements;
setDataDimensions = props.setMeasurements;
};