【问题标题】:P5 with react at 60 FPSP5 以 60 FPS 反应
【发布时间】:2018-06-12 21:39:48
【问题描述】:

为了让 P5 与 React 一起工作,我使用了 P5Wrapper 导入。

我有一个简单的starfield 动画来处理我的图块,但性能是个问题。动画在 512 个“星”对象处缓慢爬行,因此我将其缩放回 128。然而,即使在 128 时,FPS 似乎也太低了,平均低于 30 FPS。我正在寻找方法来加快 P5 在 React 中的性能,以便动画可以运行接近 60 FPS。

P5 代码:

function sketch (p) {

  const star = () => {
    const x = p.random(-TILE_SIZE/2, TILE_SIZE/2)
    const y = p.random(-TILE_SIZE/2, TILE_SIZE/2)
    const z = p.random(TILE_SIZE)
    return { x, y, z }
  }

  const stars = new Array(128)

  p.setup = () => {
    p.createCanvas(TILE_SIZE, TILE_SIZE)

    for (let i = 0; i < stars.length; i++) {
      stars[i] = star()
    }
  }

  const update = (coord) => {
    const { z } = coord
    let newZ = z - 8
    if (newZ < 1) {
      newZ = p.random(TILE_SIZE)
    }
    return { ...coord, z: newZ }
  }

  const show = (coord) => {
    const { x, y, z } = coord
    p.fill(255)
    p.noStroke()

    const sx = p.map(x / z, 0, 1, 0, TILE_SIZE)
    const sy = p.map(y / z, 0, 1, 0, TILE_SIZE)

    const r = p.map(z, 0, TILE_SIZE, 4, 0)
    p.ellipse(sx, sy, r, r)
  }

  p.draw = () => {
    p.background(0)
    p.translate(TILE_SIZE/2, TILE_SIZE/2)
    for (let i = 0; i < stars.length; i++) {
      stars[i] = update(stars[i])
      show(stars[i])
    }
  }
}

P5Wrapper 是如何使用的:

import P5Wrapper from 'react-p5-wrapper'

...
render (
 <ItemContainer key={uuidv4()}>
   <header>
     {name}
     <p>{description}</p>
   </header>
   <P5Wrapper sketch={sketch} />
 </ItemContainer>
)

星空图块的实际外观(2 个图块)。

我计划根据性能添加更多动画。或者切换到 SVG。

【问题讨论】:

    标签: javascript html reactjs animation p5.js


    【解决方案1】:

    在不更改实际动画逻辑的情况下解决了帧速率问题。可能仍然需要大量的性能优化。

    我注意到,当我卸载并重新安装组件时,动画会逐渐变慢。深入研究 Github 问题会导致这篇关于 performance degradation 的帖子。发布者提供了一个从未合并的 PR 和提交,并且存储库已经一年多没有更新了。

    相反,最好删除包并在海报更新后创建自己的组件:

    import React from 'react'
    import p5 from 'p5'
    
    export default class P5Wrapper extends React.Component {
      componentDidMount() {
        this.canvas = new p5(this.props.sketch, this.wrapper)
        if( this.canvas.myCustomRedrawAccordingToNewPropsHandler ) {
          this.canvas.myCustomRedrawAccordingToNewPropsHandler(this.props)
        }
      }
    
      componentWillReceiveProps(newprops) {
        if(this.props.sketch !== newprops.sketch){
          this.canvas.remove()
          this.canvas = new p5(newprops.sketch, this.wrapper)
        }
        if( this.canvas.myCustomRedrawAccordingToNewPropsHandler ) {
          this.canvas.myCustomRedrawAccordingToNewPropsHandler(newprops)
        }
      }
    
      componentWillUnmount() {
        this.canvas.remove()
      }
    
      render() {
        return <div ref={wrapper => this.wrapper = wrapper}></div>
      }
    }
    

    这至少解决了安装和卸载组件的性能下降问题。此外,我的帧数从低于 30 帧跃升至近 60 帧。这可能是因为我也导入了最新的 P5 包,因为我不再依赖 react-p5-wrapper 进行导入。

    【讨论】:

    • 你在这方面做了更多的工作吗?我切换到你的 P5Wrapper 版本,但它仍然比独立运行慢得多(没有反应)。到目前为止,我喜欢做出反应,但这对我来说是一个障碍。请停下来!
    • 不抱歉。这是我停下来的地方。
    • 不用担心。太糟糕了,因为反应非常好,我喜欢 p5。如果你不介意我问,你最终为你的项目做了什么?切换到 SVG?
    • 我只是想测试不同的技术和库。我没有深入研究每一项,但希望是在基本层面上尝试每一项新技术。下一个应该是框架或类似的。
    猜你喜欢
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 2012-07-03
    • 2016-07-23
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多