更改画布的尺寸似乎会清除该画布上已完成的所有绘图。
是否有一个事件在画布调整大小时触发,以便我可以挂钩它并在发生时重绘?
Jemenake 的答案看起来不错,但总的来说,我建议加载提供
debounce
功能的库,因为这就是所谓的。
例如,使用 lodash,您可以执行
window.addEventListner('resize', _.debounce(onResize, 500)
。请注意,还有第三个参数,您可以在其中指定所需的行为(例如 window.addEventListner('resize', _.debounce(onResize, 500, {leading: true, trailing true})
),尽管默认值应该相当不错。
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)
}
});
})();
请注意,上面的代码是盲打的,没有经过检查。
David Mulder 的答案是一个改进,但看起来它会在 first 调整大小事件后等待 timeout 毫秒后触发。换句话说,如果在超时之前发生更多大小调整,则不会重置计时器。我正在寻找相反的东西;我想要一些东西,它会等待一点时间让调整大小事件停止,然后在“最后一个”事件之后的一定时间后触发。下面的代码就是这样做的。 当前运行的任何定时器的 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);
)。我会每隔一段时间检查一次:
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!"); } );
)之外,您是否尝试过ResizeObserver(caniuse.com)? 例如:
const pleasantText = 'There is a handle! Let\'s try relaxing while resizing the awesome canvas! ->';
onResize = (entries) => {
document.getElementsByTagName('span')[0].innerHTML =
`${pleasantText} <b>${entries[0].target.offsetWidth}x${entries[0].target.offsetHeight}</b>`;
};
const canvas = document.getElementsByTagName('canvas')[0];
const observer = new ResizeObserver(onResize);
observer.observe(canvas);
* {
overflow: hidden;
}
body > div:first-of-type {
display: grid;
place-items: center;
width: 100vw;
height: 100vh;
user-select: none;
}
body > div:first-of-type div {
display: grid;
min-width: 12em;
min-height: 6em;
width: 16rem;
height: 6rem;
background: #ccc;
overflow: auto;
place-items: center;
text-align: center;
resize: both;
grid-auto-columns: 20vw 1fr;
grid-auto-flow: column;
grid-gap: 20px;
padding: 0.4rem 0.8rem;
border-radius: 4px;
}
canvas {
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
background: #ff9;
}
<div>
<div>
<span></span>
<canvas></canvas>
</div>
</div>
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'] });
var imgDat=ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height)
调整大小后
ctx.putImageData(imgDat,0,0)