画布的JavaScript事件调整大小

ram*_*ion 20 javascript html5 canvas

看起来改变画布的尺寸会清除已在该画布上完成的任何绘图.

是否有一个在画布上触发的事件调整大小,所以我可以挂钩它并在它发生时重绘?

Kit*_*nde 8

你通常不想严格检查resize事件,因为当你进行动态调整大小时它们会激活很多,比如jQuery中的$(window).resize,而且我知道元素上没有原生的resize事件(在窗口上).我会在一段时间内检查它:

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!"); } );
Run Code Online (Sandbox Code Playgroud)

  • 最好实际连接到resize()事件并在每次触发时重新启动重绘计时器.仅当重绘计时器用完时,才会绘制图像. (7认同)
  • 我想,这已经够好了.使用`setInterval()`来表示应该是交互式的东西让我每次都感到不寒而栗. (2认同)

Jem*_*ake 8

David Mulder的答案是改进,但看起来它会在第一次调整大小事件后等待超时毫秒后触发.换句话说,如果在超时之前发生更多调整大小,则不会重置计时器.我正在寻找相反的; 我想要一些等待一段时间让调整大小事件停止的东西,然后在最后一个之后的一定时间后开火.以下代码执行此操作.

任何当前运行的计时器的ID都在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's where you fire-after-resize code goes.
    alert("Got called!");
}
setResizeHandler(callback, 1500);
Run Code Online (Sandbox Code Playgroud)


Dav*_*der 7

在未调整浏览器窗口大小的同时,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)
           }
      });
 })();
Run Code Online (Sandbox Code Playgroud)

请注意,上面的代码是盲目输入的,未经检查.