0

使用 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();

}

感谢提示,

最好的问候埃里克

4

5 回答 5

2

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

于 2009-08-10T18:39:07.293 回答
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();

    };

})();

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

于 2009-08-10T19:23:26.953 回答
1

如果通过它们的 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 万像素。只是预感,因为填充 25M 像素可能是也可能不是基于画布实现的问题。

于 2009-08-10T19:31:33.067 回答
0

I really think you should closePath() at the end

于 2009-08-12T12:07:59.587 回答
0

This might be very slow, especially for such a big surface. Try to only clear what you need instead:

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

于 2010-11-23T21:58:36.007 回答