P5 以 60 FPS 的速度做出反应
P5 with react at 60 FPS
为了让 P5 与 React 一起工作,我正在使用 P5Wrapper 导入。
我有一个简单的 starfield 动画可以在我的磁贴上运行,但是性能是个问题。动画在 512 "star" 个对象时变慢,因此我将其缩小到 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。
在不改变实际动画逻辑的情况下解决了帧率问题。可能仍然需要大量的性能优化。
我注意到当我卸载并重新安装组件时,动画变得越来越慢。深入研究 Github 问题会导致 post 关于 performance degradation。 poster 提供了一个从未合并的 PR 和提交,并且存储库已经一年多没有更新了。
相反,最好删除包并在 poster 的更新后创建您自己的组件:
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 FPS 跃升至近 60 FPS。这可能是因为我还导入了最新的 P5 包,因为我不再依赖 react-p5-wrapper 来进行导入。
为了让 P5 与 React 一起工作,我正在使用 P5Wrapper 导入。
我有一个简单的 starfield 动画可以在我的磁贴上运行,但是性能是个问题。动画在 512 "star" 个对象时变慢,因此我将其缩小到 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。
在不改变实际动画逻辑的情况下解决了帧率问题。可能仍然需要大量的性能优化。
我注意到当我卸载并重新安装组件时,动画变得越来越慢。深入研究 Github 问题会导致 post 关于 performance degradation。 poster 提供了一个从未合并的 PR 和提交,并且存储库已经一年多没有更新了。
相反,最好删除包并在 poster 的更新后创建您自己的组件:
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 FPS 跃升至近 60 FPS。这可能是因为我还导入了最新的 P5 包,因为我不再依赖 react-p5-wrapper 来进行导入。