【问题标题】:Slow Canvas Element慢画布元素
【发布时间】:2010-11-18 09:24:22
【问题描述】:

使用 Canvas 元素,我从一个元素到另一个元素绘制一条线 另一个元素是可拖动的,当拖动元素时,线条会跟随可拖动元素。

我的问题是渲染速度很慢(Mac PowerBook 上的 Fx 3.5) 我想我之前在 Canvas 中看到过更好的性能

任何有 Canvas 经验的人可以提供一些性能提示吗?

提前致谢

在拖拽事件上调用以下方法,

// Runs when the element is dragged.
function onDrag(key)
{
  var ctx = canvas.context;
  var fromRect = $('#box-' + key).offset();
  var fromHeight = $('#box-' + key).height();
  var fromWidth = $('#box-' + key).height();

  var toRect = $('#draggable').offset();
  var toWidth = $('#draggable').width();

  var startX = toRect.left + toWidth / 2;
  var startY = toRect.top + 4;
  var endX = fromRect.left + fromWidth / 2;
  var endY = fromRect.top + fromHeight / 2;

  ctx.clearRect(0, 0, 5000, 5000);
  ctx.beginPath();
  ctx.moveTo(startX, startY);
  ctx.lineTo(endX, endY);
  ctx.strokeStyle = "rgba(0, 0, 0,1)";
  ctx.stroke();

}

感谢您的提示,

最好的问候埃里克

【问题讨论】:

  • 你用过profiler吗?正如“未知(雅虎)”所说,您的瓶颈可能是所有这些高度、宽度、偏移量测量值。

标签: javascript canvas draggable drag


【解决方案1】:

我敢打赌,jQuery 函数调用比绘图花费的时间更长。如果您的应用程序允许您在不使用 jQuery 的情况下轻松计算偏移量和尺寸,那么您也许可以在那里提取一些额外的速度。

【讨论】:

    【解决方案2】:

    在可能的情况下,缓存 jQuery 选择:

    var onDrag = (function(){
    
        var draggable = $('#draggable'),
            ctx = canvas.context; // btw, don't you mean canvas.getContext('2d')?
    
        return function(key) {
    
            var box = $('#box-' + key),
                fromRect = box.offset(),
                fromHeight = box.height(),
                fromWidth = box.height(),
                toRect = draggable.offset(),
                toWidth = draggable.width(),
                startX = toRect.left + toWidth / 2,
                startY = toRect.top + 4,
                endX = fromRect.left + fromWidth / 2,
                endY = fromRect.top + fromHeight / 2;
    
            ctx.clearRect(0, 0, 5000, 5000);
            ctx.beginPath();
            ctx.moveTo(startX, startY);
            ctx.lineTo(endX, endY);
            ctx.strokeStyle = "rgba(0, 0, 0,1)";
            ctx.stroke();
    
        };
    
    })();
    

    一般规则:如果您有一个要快速连续运行多次的函数,那么请确保您只在每次调用该函数时执行绝对必须完成。 p>

    【讨论】:

      【解决方案3】:

      如果通过元素的 id 定位元素并读取它们的尺寸是瓶颈,你可以尝试记忆你的函数:

      function onDrag(key) {
          var cached = onDrag.cache[key];
      
          if (!cached) {
              cached = {
                  fromRect = $('#box-' + key).offset();
                  // etc.
              };
      
              onDrag.cache[key] = cached;
          }
      
          var toRect = $('#draggable').offset();
          // etc.
      }
      
      onDrag.cache = {};
      

      可能会给你一些性能提升。

      另外,您可以尝试取出clearRect() 看看它是否有很大的不同?您可能想要存储上一次拖动的位置,然后只回溯上一行以将其擦除,而不是绘制 5000 x 5000 = 2500 万像素。只是预感,因为填充 2500 万像素可能是也可能不是基于画布实现的问题。

      【讨论】:

        【解决方案4】:

        我真的认为你应该在最后关闭路径()

        【讨论】:

          【解决方案5】:

          这可能会很慢,尤其是对于这么大的表面。试着只清除你需要的东西:

          ctx.clearRect(0, 0, 5000, 5000);

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-08-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-29
            • 2014-11-27
            • 1970-01-01
            • 2012-01-12
            相关资源
            最近更新 更多