画布的JavaScript事件调整大小

时间:2011-04-28 21:47:04

标签: javascript html5 canvas

似乎更改画布的尺寸会清除已在该画布上完成的任何绘图。

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

5 个答案:

答案 0 :(得分:8)

你通常不想严格检查调整大小事件,因为它们在你进行动态调整大小时会激活很多,比如jQuery中的$(window).resize,到目前为止我知道没有本机调整大小事件on elements(there is on window)。我会在一段时间内检查它:

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!"); } );

答案 1 :(得分:8)

David Mulder的回答是改进,但看起来它会在第一次调整大小事件后等待超时毫秒后触发。换句话说,如果在超时之前发生更多调整大小,它不会重置计时器。我正在寻找相反的;我想要一些等待一段时间让调整大小事件停止的东西,然后在 last 之后的一段时间后触发。以下代码就是这样做的。

当前正在运行的计时器的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);

答案 2 :(得分:7)

在未调整浏览器窗口大小的情况下,套件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)
           }
      });
 })();

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

答案 3 :(得分:1)

我没有找到任何内置事件来检测新的画布尺寸,因此我尝试找到两种情况的解决方法。

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'] });
  1. 为了检测任何JavaScript canvas.style更改,MutationObserver API很适合。它没有检测到特定的样式属性,但是 在这种情况下,检查canvas.clientWidth和canvas.clientHeight是否已更改就足够了。

  2. 如果在具有百分比单位的样式标记中声明画布大小,则使用JavaScript正确解释css选择器(>,*,:: before,...)时会遇到问题。我认为在这种情况下,最好的方法是设置window.resize处理程序并检查画布客户端大小。

答案 4 :(得分:-1)

将画布状态保存为imageData,然后在调整大小后重绘

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

调整大小后

ctx.putImageData(imgDat,0,0)