Javascript 慢画布元素

Javascript 慢画布元素,javascript,canvas,draggable,drag,Javascript,Canvas,Draggable,Drag,使用Canvas元素,我从一个元素到另一个元素画了一条线 另一个元素是可拖动的,当拖动该元素时,该行跟随可拖动的元素 我的问题是渲染速度很慢(Mac PowerBook上的Fx 3.5) 我想我以前在画布上看到过更好的表现 有画布经验的人可以提供一些性能提示吗 提前谢谢 在拖动事件上调用以下方法 // Runs when the element is dragged. function onDrag(key) { var ctx = canvas.context; var fromRec

使用Canvas元素,我从一个元素到另一个元素画了一条线 另一个元素是可拖动的,当拖动该元素时,该行跟随可拖动的元素

我的问题是渲染速度很慢(Mac PowerBook上的Fx 3.5) 我想我以前在画布上看到过更好的表现

有画布经验的人可以提供一些性能提示吗

提前谢谢

在拖动事件上调用以下方法

// 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();
}

谢谢你的提示


向Eric致意

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

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

如果可能,缓存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();

    };

})();


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

如果可能,缓存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();

    };

})();


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

如果通过元素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万像素可能是一个问题,也可能不是一个问题。

如果通过元素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万像素可能是一个问题,也可能不是一个问题。

我真的认为您应该在结尾关闭path()

我真的认为您应该在结尾关闭path()

这可能非常慢,尤其是对于如此大的曲面。尝试只清除您需要的内容:


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

这可能非常缓慢,尤其是对于如此大的曲面。尝试只清除您需要的内容:

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

你用过探查器吗?正如“未知(yahoo)”所说,您的瓶颈可能是所有这些高度、宽度和偏移测量值。您使用过探查器吗?正如“未知(yahoo)”所说,您的瓶颈可能是所有这些高度、宽度和偏移测量。