Медленный холст - PullRequest
       38

Медленный холст

0 голосов
/ 10 августа 2009

Используя элемент Canvas, я рисую линию от одного элемента к другому Другой элемент является перетаскиваемым, и при перетаскивании элемента линия следует за перетаскиваемым элементом.

Моя проблема в том, что рендеринг появляется медленно (Fx 3.5 на Mac PowerBook) Мне кажется, я видел гораздо лучшую производительность в 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();

}

Спасибо за советы,

С наилучшими пожеланиями, Эрик

Ответы [ 5 ]

2 голосов
/ 10 августа 2009

Где возможно, кэшируйте выборки 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();

    };

})();

Общее правило: Если у вас есть функция, которая будет запускаться несколько раз подряд, убедитесь, что вы делаете только то, что АБСОЛЮТНО ДОЛЖНО БЫТЬ СДЕЛАНО при каждом вызове функции.

2 голосов
/ 10 августа 2009

Я хотел бы поспорить, что вызовы функций jQuery занимают больше времени, чем рисование. Если ваше приложение позволяет легко вычислять смещение и размеры без использования jQuery, возможно, вы сможете извлечь дополнительную скорость.

1 голос
/ 10 августа 2009

В случае, если поиск элементов по их идентификаторам и считывание их размеров является узким местом, вы можете попытаться запоминать свою функцию:

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 = 25 миллионов пикселей. Просто догадка, поскольку заполнение 25M пикселей может или не может быть проблемой, основанной на реализации canvas.

0 голосов
/ 24 ноября 2010

Это может быть очень медленно, особенно для такой большой поверхности. Попробуйте очистить только то, что вам нужно:

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

0 голосов
/ 12 августа 2009

Я действительно думаю, что вы должны закрытьPath () в конце

...