优化简单的PixiJS阶段

时间:2018-08-09 10:49:11

标签: performance canvas webgl pixi.js

我对Pixi,WebGL,Canvas完全陌生,实际上我不是在做游戏,而是React Webapp

我要构建的东西:

  • 绘制图像(A4文档扫描,通常从100k到1m为jpeg / png)
  • 在图像的每个单词上方,绘制一个可以悬停/单击的交互式矩形
  • 多亏了深度学习/ OCR,我已经有了图像的大小和文档单词的相对位置
  • 文档可以包含0到3000个单词
  • 缩放能力

enter image description here

我首先尝试使用常规CSS,但是清楚地发现,使用位置绝对值无法在文档上定位数千个矩形:例如,在滚动显示时效果不佳。

我尝试使用PixiJS在图像顶部绘制矩形。结果更好,但是我仍然在旧计算机上看到一些性能问题,尤其是在缩放图像时(它会影响滚动,因此与我猜想的JS代码并不真正相关)


结果是:https://dhatim-poc-mlhafeauav.now.sh/

我用于上述文档的解决方案:

  • 一个html img标签
  • 位于图像顶部的透明画布,在其上绘制矩形(Graphics,drawRect)

有人可以告诉我如何针对较旧的计算机进行优化吗? 如何正确审核此解决方案的性能? 有没有一种简便的方法可以在我的开发环境中模拟旧计算机?特别是关于GPU而不是CPU节流?


我尝试遵循此处找到的一些建议:https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas

  • 我使用背景图片而不是将图片绘制到画布上(不确定是否会产生很大的影响,因为没有“游戏循环”)
  • 我将Math.floor用于单词的位置(PixiJS roundPixels选项)
  • 我还尝试了一块小画布和一个比例转换:https://build-ybbdwoumva.now.sh/

您还有其他建议可以提高性能吗?

特别是:

  • 我应该将Sprite还是Graphics用于矩形?
  • 我应该使用canvas还是WebGL?
  • 如何衡量我的性能优化?我目前感到自己完全盲目,甚至不确定在没有具体数字的情况下我所做的事情会带来更好的结果

谢谢

1 个答案:

答案 0 :(得分:1)

如果将所有矩形元素放在父元素中并在该元素上设置style.transform比例,该怎么办。然后,您只需要更新一个元素即可缩放。

const parent = document.querySelector(".areas>div");
const pair = document.querySelector(".viewer>div");

const imgWidth = 600;
const imgHeight = 849;
const numAreas = 1000;
for (let i = 0; i < numAreas; ++i) {
  const x = rand(imgWidth - 10);
  const y = rand(imgHeight - 10);
  const w = rand(5, imgWidth - x);
  const h = rand(5, imgHeight - y);
  
  const area = document.createElement("div");
  area.className = "area";
  area.style.left = px(x);
  area.style.top = px(y);
  area.style.width = px(w);
  area.style.height = px(h);
  parent.appendChild(area);
}

document.querySelector("#zoom").addEventListener('input', (e) => {
  const s = e.target.value / 100;
  const transform = `scale(${s},${s})`;
  pair.style.transform = transform;
});

function rand(min, max) {
  if (max === undefined) {
    max = min;
    min = 0;
  }
  return Math.random() * (max - min) + min | 0;
}

function px(v) {
  return `${v}px`;
}
html { box-sizing: border-box; }
*, *:before, *:after { box-sizing: inherit; }
.viewer {
  position: relative;  /* so children are relative to this */
}
.area { 
  border: 1px solid red;
}
.area:hover {
  border: 1px solid yellow;
}
.areas {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  /* to match image */
  width: 600px;
  height 849px;
}
.areas>div {
  position: relative;  /* so children are relative to this */
  width: 100%;
  height: 100%;
}
.areas>div>div {
  position: absolute;
}
.ui {
  position: absolute;
  left: 1em;
  top: 1em;
  background: rgba(0,0,0,.8);
  color: white;
  padding: .5em;
  z-index: 3;
}
.ui>input {
  width: 100%;
}
<div class="viewer">
  <div>
    <img src="https://i.imgur.com/TSiyiJv.jpg">
    <div class="areas">
      <div>
      </div>
    </div>
  </div>
</div>
<div class="ui">
 <label for="zoom">zoom</label>
 <input type="range" min="1" max="500" value="100" id="zoom">
</div>

我没有打扰清理它或设置滚动条等,但是它似乎可以工作