代码之家  ›  专栏  ›  技术社区  ›  Sebastien Lorber

优化简单PixiJS阶段

  •  0
  • Sebastien Lorber  · 技术社区  · 8 年前

    我对Pixi,WebGL,Canvas都不熟悉。。。实际上,我不是在做游戏,而是在做一个React webapp

    • 绘制图像(A4文档扫描,通常是从100k到1m的jpeg/png)
    • 多亏了深入的学习/OCR,我已经掌握了图像的大小和文档单词的相对位置
    • 缩放能力

    enter image description here

    我首先尝试使用常规CSS,但很明显发现使用position absolute并不能在文档上定位数千个矩形:例如,在滚动上的性能就不好。

    我试着用PixiJS在图像上画矩形。结果更好,但我仍然看到我的旧计算机上的一些性能问题,特别是当图像被缩放时(它会影响滚动,所以我猜它与JS代码没有关系)


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

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

    • html img标记
    • 一块透明的画布,放在图像的顶部,我在上面画矩形(图形,drawRect)

    有人能告诉我如何为旧电脑优化这个吗? 如何正确审核此解决方案的性能? 有没有一种简单的方法可以在我的dev env上模拟一台旧计算机?特别是关于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?
    • 我应该用画布还是WebGL?

    谢谢

    1 回复  |  直到 8 年前
        1
  •  1
  •   gman    8 年前

    如果将所有矩形元素放在父元素中,并在该元素上设置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>

    我没有费心清理它或设置滚动条等,但它似乎工作了

    推荐文章