Событие JavaScript для изменения размера холста

Похоже, что изменение размеров холста очищает любой чертеж, уже сделанный на этом холсте.

Есть ли событие, которое срабатывает при изменении размера холста, поэтому я могу его перехватить и перерисовать, когда это произойдет?

Ответы

Ответ 1

Обычно вы не хотите строго проверять событие с изменением размера, потому что они много горят, когда вы выполняете динамическое изменение размера, например $(window).resize в jQuery, и насколько мне известно, Элементы (есть в окне). Я бы проверял его на интервале:

function onResize( element, callback ){
  var elementHeight = element.height,
      elementWidth = element.width;
  setInterval(function(){
      if( element.height !== elementHeight || element.width !== elementWidth ){
        elementHeight = element.height;
        elementWidth = element.width;
        callback();
      }
  }, 300);
}

var element = document.getElementsByTagName("canvas")[0];
onResize( element, function(){ alert("Woo!"); } );

Ответ 2

Ответ Дэвида Малдера - это улучшение, но похоже, что он будет вызываться после ожидания через миллисекунды после первого события изменения размера. Другими словами, если больше изменений произойдет до таймаута, это не reset таймер. Я искал обратное; Мне нужно было что-то, что подождало бы немного времени, чтобы события изменения размера прекратились, а затем огонь через некоторое время после последнего. Следующий код делает это.

Идентификатор любого текущего таймера будет находиться в timer_id. Таким образом, всякий раз, когда есть размер, он проверяет, не работает ли уже время. Если это так, он отменяет это и запускает новый.

function setResizeHandler(callback, timeout) {
    var timer_id = undefined;
    window.addEventListener("resize", function() {
        if(timer_id != undefined) {
            clearTimeout(timer_id);
            timer_id = undefined;
        }
        timer_id = setTimeout(function() {
            timer_id = undefined;
            callback();
        }, timeout);
    });
}

function callback() {
    // Here where you fire-after-resize code goes.
    alert("Got called!");
}
setResizeHandler(callback, 1500);

Ответ 3

Ответ на Kit Sunde сделает много ненужной работы, пока окно браузера не будет изменено. Лучше проверить, изменилось ли событие в ответ на событие браузера, а затем проигнорировать события изменения размера за определенное количество времени, после которого вы снова проведете проверку (это приведет к двум проверкам после каждой последовательности в быстрой последовательности, и код может быть чтобы предотвратить это, но вы, вероятно, получите идею).

 (function(){
      var doCheck = true;
      var check = function(){
           //do the check here and call some external event function or something.
      };
      window.addEventListener("resize",function(){
           if(doCheck){
                check();
                doCheck = false;
                setTimeout(function(){
                     doCheck = true;
                     check();
                },500)
           }
      });
 })();

Обратите внимание, что код выше был напечатан вслепую и не отмечен.

Ответ 4

сохранить состояние canvas как imageData, а затем перерисовать его после изменения размера

var imgDat=ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height)

после изменения размера

ctx.putImageData(imgDat,0,0)

Ответ 5

Я не обнаружил никаких встроенных событий для обнаружения новых размеров холста, поэтому я попытался найти обходной путь для двух сценариев.

function onresize()
{
    // handle canvas resize event here
}

var _savedWidth = canvas.clientWidth;
var _savedHeight = canvas.clientHeight;
function isResized()
{
    if(_savedWidth != canvas.clientWidth || _savedHeight != canvas.clientHeight)
    {
        _savedWidth = canvas.clientWidth;
        _savedHeight = canvas.clientHeight;
        onresize();
    }
}

window.addEventListener("resize", isResized);

(new MutationObserver(function(mutations)
{
    if(mutations.length > 0) { isResized(); }
})).observe(canvas, { attributes : true, attributeFilter : ['style'] });
  • Для обнаружения любых изменений canvas.style в JavaScript подходит API MutationObserver. Он не обнаруживает свойства определенного стиля, но в этом случае достаточно проверить, изменилось ли canvas.clientWidth и canvas.clientHeight.

  • Если размер холста объявлен в теге style с единицей процента, у нас есть проблема правильно интерпретировать селектор css ( > , *,:: before,...) с помощью JavaScript. Я думаю, что в этом случае лучший способ - установить обработчик window.resize, а также проверить размер клиента canvas.