javascript - 为什么这个 Canvas 代码这么慢?

标签 javascript canvas webgl

我有简短的代码,可以在这些轨道上绘制圆(轨道)点(卫星)。卫星绕着轨道运行。事实上代码不是我的,但我被要求解决问题。

根据 chrome 和 firefox 中的分析器,函数 drawSatellite 占用 50%-100% cpu,我想知道为什么。

Canvas 与您的窗口一样大 (1920x1080)。大约有 160 个轨道(随着时间页面在线而增加)。

这是drawSatellite:

OrbitBackground.prototype.drawSatellite = function(ctx, satellite) {
  ctx.fillStyle = satellite.satellite.fill;
  ctx.beginPath();

  if (++satellite.satellite.angularPosition == 360)
    satellite.satellite.angularPosition = 0;

  // 1 FPS = 60 calls => 180 / 6 (6-times faster @ 60 FPS) = 30
  var radians = satellite.satellite.angularPosition * Math.PI / 30 / satellite.rps;

  if (satellite.backward)
    radians = -radians;

  ctx.arc(
      satellite.satellite.x + satellite.orbit.radius * Math.cos(radians),
      satellite.satellite.y + satellite.orbit.radius * Math.sin(radians),
      satellite.satellite.radius,
      0,
      Math.PI*2,
      true
  );
  ctx.closePath();
  ctx.fill();
};

调用它的函数:

OrbitBackground.prototype.drawFrame = function() {
  if (this.running)
    requestAnimationFrame(this.drawFrame.bind(this));

  this.dynamicStageCtx.clearRect(0, 0, this.pageWidth, this.pageHeight);

  for (var i=0; i < this.orbits.length; i++) {
    this.drawSatellite(this.dynamicStageCtx, this.orbits[i]);
  }
};

最佳答案

你这样做:

Loop:
    set fill style
    begin path
    make path
    end path
    fill

这样做会更快:

set fill style (just once, before loop)
begin path (just one path, with loop-number of subpaths)
Loop:
    moveTo (start of subpath)
    make path
    close path
fill (just once, after loop)

但这要求每颗卫星的填充样式都相同。如果只有几种颜色,您可以尝试按颜色将它们组合在一起。

另请注意,计算余弦和正弦很慢(所有三 Angular 函数和平方根调用都很慢),如果您能避免使用它们,您会过得更好。

Canvas 的大小(像素数)也很重要。考虑将 Canvas 缩小一半或四分之一(960x540 或 480x270)并使用 CSS 将其放大。

关于javascript - 为什么这个 Canvas 代码这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23427781/

相关文章:

javascript - 如何将方法附加到对象以更改 CSS

javascript - Prototype 最好的字段验证插件是什么?

javascript - 获取对象 HTMLImageElement 而不是 base64 字符串

html - 如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果

javascript - 读取 WebGLTexture 中的像素(将 WebGL 渲染到纹理)

javascript - 使用纯 javascript 或纯 css 水平和垂直居中表单和 div

javascript - Angular js ng-bind-html 在输入 `{_}` 上没有给出任何输出

java - 坚持 View 滚动以跟随 Sprite

javascript - WebGL 警告 : "Attribute 0 is disabled. This has significant performance penalty"

colors - 为什么片段着色器根据片段坐标将图像着色为饱和色?