我的反应应用程序包含不断重复的 p5 草图

Posted

技术标签:

【中文标题】我的反应应用程序包含不断重复的 p5 草图【英文标题】:my react app contains p5 sketches that keep repeating 【发布时间】:2021-07-17 17:56:17 【问题描述】:

我目前正试图在我的 React 应用程序中实现 p5 草图。我试图更改工具栏的 z 索引,以便 p5 元素位于下方,但是当我这样做时,它们会不断重复。您可以看到存储库 here 的链接(草图位于 bio 和 contact 文件夹中)。

我知道这可能与草图的实例模式有关,但是我对 React 非常陌生,并且不熟悉正确的语法。

如果有人有任何建议,请随时与我们联系!

【问题讨论】:

您应该尝试将您的代码减少到一个最小的可重现示例 (***.com/help/minimal-reproducible-example)。如果可能,请将其作为可运行的 sn-p 添加到您的问题中,如果不可能,请将代码的相关部分作为格式化的代码块包含在内,并链接到您的代码的可运行实例,例如 replit.com 或故障。 com 【参考方案1】:

我无法重现您的问题,但这里是您的 React 应用程序的一个显着简化的版本,可以嵌入到 *** 中:

// Modification: Pass the container element to a function when returns the
// actual sketch function. This way we don't have to get the container
// element by id.
const biosketch = (container) => 
  return (p) => 
    p.setup = () => 
      let c = p.createCanvas(container.offsetWidth, container.offsetHeight);
      // This was missing from your code, so that may have been causing problems.
      // An alternative to setting the canvas parent this way is to pass the
      // parent to the p5 constructor.
      c.parent(container);

      p.angleMode(p.DEGREES);
      p.rectMode(p.CENTER);
    

    p.draw = () => 
      p.background(0, 20);
      let time = p.frameCount;
      let iter = p.map(p.accelerationX, -90, 90, 0, 3);
      let col = p.map(p.accelerationY, -90, 90, 0.02, 3.5);

      p.translate(p.width / 2, p.height / 2);

      for (var i = 0; i < 200; i++) 
        p.push();
        p.rotate(p.cos(p.frameCount + i * iter) * 80);
        p.stroke(127 + 127 * p.sin(i * col + time), 127 + 127 * p.sin(i * 2 + time), 127 + 127 * p.sin(i * 0.5 + time));
        p.noFill();
        p.rect(0, 0, 620 - i * 3.12, 620 - i * 3.12, 200 - i);
        p.pop();
      
    

    p.windowResized = () => 
      p.resizeCanvas(canvas.offsetWidth, canvas.offsetHeight)
      p.background(0);
    
  


function Bio() 
  const containerRef = React.useRef();

  React.useEffect(() => 
    console.log('initializing effect');
    const sketch = new p5(bioSketch(containerRef.current));

    // The return value form useEffect is a callback to remove the effect
    return () => 
      console.log('cleaning up effect');
      sketch.remove();
    
  , []);

  return <div id='canvas-container' ref=containerRef />;


class App extends React.Component 
  constructor(props) 
    super();
    this.state =  showSketch: true ;
  
  
  render() 
    return (
    <React.Fragment>
      this.state.showSketch && <Bio />
      <button onClick=() => this.setState( showSketch: this.state.showSketch ? false : true )>
        Toggle
      </button>
    </React.Fragment>
    );
  


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
#canvas-container 
  width: 200px;
  height: 200px;
  float: left;
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
</head>

<body>
  <div id="root"></div>
</body>

</html>

这看起来对我来说基本上是有效的,所以显然我在简化代码方面走得太远了,并删除了导致问题的任何东西。由你来介绍足以证明问题的内容,而不会使无关的组件、样式和路由过于复杂。

有关如何在 *** 问题中嵌入 ReactJS 代码的更多信息,请参阅this question。

【讨论】:

感谢您的反馈,我在 setup 函数中添加了您建议的代码(let c = p.createCanvas),它似乎解决了 p5 草图在不同页面之间重复的问题。但是,当您单击每个选项卡时,它们似乎仍在彼此上方绘制草图的新实例,从而导致它们变慢。有没有办法在不使用时有效地擦除每个元素?我认为这可能与 useRef() ? @Harry 我已经更新了我的示例来展示如何清理你的效果。我还改进了草图组件,使其对容器元素使用 ref,以消除对 getElementById() 的使用。

以上是关于我的反应应用程序包含不断重复的 p5 草图的主要内容,如果未能解决你的问题,请参考以下文章

无法实例化 p5.js 代码(实例模式)

反应本机推送通知(Android) - 通知不断重复并且不会停止

抖动 (Floyd-Steinberg) 仅更新 p5.js 中的部分图形对象

创建反应应用程序:setupProxy 不断返回被 CORS 策略阻止的 401,不适用于远程 URL?

Web 套接字在反应应用程序中不断断开连接。后端是 Nestjs

编译器警告“找不到模块:错误:无法解析'./locale'”,因为我在我的反应应用程序中使用了 momentjs [重复]