Javascript 使用React优化高复杂度图形画布的最佳方法?

Javascript 使用React优化高复杂度图形画布的最佳方法?,javascript,html,reactjs,html5-canvas,fractals,Javascript,Html,Reactjs,Html5 Canvas,Fractals,我和一个朋友正在玩分形,想建立一个互动网站,在那里你可以改变生成分形的值,你可以看到它是如何影响生活的。在小分辨率测试中,该网站的响应速度相当快,但仍然很慢 drawFractal = () => { for (let x = 0; x < this.canvas.width; x++) { for (let y = 0; y < this.canvas.height; y++) { const belongsToSet = this.checkIfBe

我和一个朋友正在玩分形,想建立一个互动网站,在那里你可以改变生成分形的值,你可以看到它是如何影响生活的。在小分辨率测试中,该网站的响应速度相当快,但仍然很慢

drawFractal = () => {
  for (let x = 0; x < this.canvas.width; x++) {
    for (let y = 0; y < this.canvas.height; y++) {
      const belongsToSet = this.checkIfBelongsToMandelbrotSet(x / this.state.magnificationFactor - this.state.panX, y / this.state.magnificationFactor - this.state.panY);
      if (belongsToSet === 0) {
        this.ctx.clearRect(x,y, 1,1);
      } else {
        this.ctx.fillStyle = `hsl(80, 100%, ${belongsToSet}%)`;
        // Draw a colorful pixel
        this.ctx.fillRect(x,y, 1,1);
        }
      }
    }
}

checkIfBelongsToMandelbrotSet = (x,y) => {
  let realComponentOfResult = x;
  let imaginaryComponentOfResult = y;
  // Set max number of iterations
  for (let i = 0; i < this.state.maxIterations; i++) {
    const tempRealComponent = realComponentOfResult * realComponentOfResult - imaginaryComponentOfResult * imaginaryComponentOfResult + x;
    const tempImaginaryComponent = this.state.imaginaryConstant * realComponentOfResult * imaginaryComponentOfResult + y;
    realComponentOfResult = tempRealComponent;
    imaginaryComponentOfResult = tempImaginaryComponent;
    // Return a number as a percentage
    if (realComponentOfResult * imaginaryComponentOfResult > 5) {
      return (i / this.state.maxIterations * 100);
    }
  }
  // Return zero if in set
  return 0;
}
drawFractal=()=>{
for(设x=0;x{
让realComponentOfResult=x;
设结果的ImaginaryComponent=y;
//设置最大迭代次数
for(设i=0;i5){
返回(i/this.state.maxIterations*100);
}
}
//如果在集合中,则返回零
返回0;
}

这是处理分形生成的算法。然而,我们迭代画布的每个像素,这是非常低效的。因此,整个网站的速度非常慢。我想问,使用html画布是一个好主意,还是有更有效的替代方案?或者我可以优化drawFractal()函数以提高效率?我不知道如何从这一点上继续下去,因为我没有经验,将感谢任何反馈

尽可能避免喷漆操作

当您执行
fillRect(x,y,1,1)
时,浏览器必须每像素从CPU转到GPU一次,这是非常低效的

在您的例子中,由于您自己绘制每个像素,因此您可以简单地将所有这些像素设置为一个像素,并将完整图像每帧放置一次

为了稍微改进颜色设置,我在手之前生成了一个包含100个值的数组,如果您愿意,可以使其更细粒度

您的Mandelbrot可能有改进,我没有检查,但这比StackOverflow更适合

下面是一个使用800x600px画布的简单演示:

const state={
放大系数:5000,
想象常数:1,
最大迭代次数:20,
panX:1,
公司:1
};
const canvas=document.getElementById('canvas');
const width=canvas.width=800;
const height=canvas.height=600;
const ctx=canvas.getContext('2d');
//我们将在其上绘制的图像数据
const img=新的图像数据(宽度、高度);
//创建一个Uint32视图,这样我们就可以在一次操作中设置一个像素
const img_data=新的uint32阵列(img.data.buffer);
常量drawFractal=()=>{
对于(设x=0;x{
让realComponentOfResult=x;
设结果的ImaginaryComponent=y;
//设置最大迭代次数
for(设i=0;i5){
返回(i/state.maxIterations*100);
}
}
//如果在集合中,则返回零
返回0;
}
//我们在init生成所有颜色,而不是生成每一帧
const colors=Array.from({length:100},(u,i)=>{
如果(!i){返回0;}
返回hslToRgb(80/360、100/100、i/100);
} );
函数getColor(比率){
如果(比率===0){返回0;}
返回颜色[数学圆整(比率)];
}
函数anim(){
状态放大系数-=10;
drawFractal();
请求动画帧(anim);
}
请求动画帧(anim);
//mjijackson.com原创
//借来https://stackoverflow.com/a/9493060/3702797
函数hslToRgb(h、s、l){
var r,g,b;
如果(s==0){
r=g=b=l;//消色差
}否则{
var hue2rgb=函数hue2rgb(p,q,t){
如果(t<0)t+=1;
如果(t>1)t-=1;
如果(t<1/6)返回p+(q-p)*6*t;
如果(t<1/2)返回q;
如果(t<2/3)返回p+(q-p)*(2/3-t)*6;
返回p;
}
var q=l<0.5?l*(1+s):l+s-l*s;
var p=2*l-q;
r=hue2rgb(p,q,h+1/3);
g=hue2rgb(p,q,h);
b=hue2rgb(p,q,h-1/3);
}
//我们需要0xAABBGGRR格式
函数toHex(val){
返回Math.round(val*255).toString(16);
}
返回编号('0xFF'+toHex(b)+toHex(g)+toHex(r));
}

Hello@Middle,令人印象深刻的项目,但您的问题更像是项目的广告和推荐页面,而不是问题。请签出页面并重新编辑您的que