HTML画布 - 改变大小时绘制消失

24

我已经在HTML画布元素中创建了一个基本形状,它正常工作。

当我重新调整画布大小时,所有画在画布上的内容都会消失。这是正常行为吗?还是有可以用来停止这种情况发生的函数呢?

解决这个问题的方法之一可能是在画布大小调整时再次调用绘图函数,但如果要绘制的内容很多,这可能不是非常有效。

那么最好的方法是什么呢?

这里是示例代码的链接:https://gist.github.com/2983915


在调整大小时重新绘制没有问题。通常有许多情况需要重新绘制画布,这是可以接受的。画布绘制速度很快。 - Denys Séguret
重新调整大小时重新绘制...许多画布应用程序每秒重新绘制画布甚至达到60次/秒(60FPS),因此这没有问题。 - XCS
7个回答

32

当你改变大小时,需要重新绘制场景。

设置画布的宽度或高度,即使将其设置为之前的相同值,不仅会清除画布,还会重置整个画布上下文。任何已设置的属性(fillStylelineWidth、剪切区域等)也将被重置。

如果你没有从代表画布的任何数据结构中重绘场景的能力,你可以通过将其绘制到一个内存画布上,保存整个画布本身,然后设置原始宽度并将内存画布绘制回原始画布。

以下是一个快速保存画布位图并在调整大小后放回的例子:

http://jsfiddle.net/simonsarris/weMbr/


一直在为画布拉伸而努力,从未注意到这种行为。嗯... 直到现在。 - jayarjo

5
每次调整画布大小时,它都会重置为透明黑色,就像规范中定义的那样。
你要么在调整画布大小时重新绘制,要么就不要调整画布大小。

1

当我需要调整画布以适应屏幕时,我遇到了同样的问题。但是我用这段代码解决了它:

var c = document.getElementById('canvas');
ctx = c.getContext('2d');
ctx.fillRect(0,0,20,20);
// Save canvas settings
ctx.save();
// Save canvas context
var dataURL = c.toDataURL('image/jpeg');
// Resize canvas
c.width = 50;
c.height = 50;
// Restore canvas context
var img = document.createElement('img');
img.src = dataURL;
img.onload=function(){
  ctx.drawImage(img,20,20);
}
// Restote canvas settings
ctx.restore();
<canvas id=canvas width=40 height=40></canvas>


1

如果您关心性能,另一种方法是使用防抖动技术。它不会在您拖动时重新调整或重绘每个位置,而仅在其大小调整时进行调整。

 // Assume canvas is in scope
 addEventListener.("resize", debouncedResize );

 // debounce timeout handle
 var debounceTimeoutHandle;

 // The debounce time in ms (1/1000th second)
 const DEBOUNCE_TIME = 100; 

 // Resize function 
 function debouncedResize () { 
    clearTimeout(debounceTimeoutHandle);  // Clears any pending debounce events

 // Schedule a canvas resize 
 debounceTimeoutHandle = setTimeout(resizeCanvas, DEBOUNCE_TIME);
 }

 // canvas resize function
 function resizeCanvas () { ... resize and redraw ... }

0

我曾经遇到过同样的问题。尝试使用以下代码:

var wrapper = document.getElementById("signature-pad");
var canvas = wrapper.querySelector("canvas");
var ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;

它保持了绘图的原样


0
在编程中,有一件事对我很有效,那就是使用 requestAnimationFrame()
let height = window.innerHeight;
let width = window.innerWidth;

function handleWindowResize() {
    height = window.innerHeight;
    width = window.innerWidth;
}

function render() {
    // Draw your fun shapes here
    // ...

    // Keep this on the bottom
    requestAnimationFrame(render);
}

// Canvas being defined at the top of the file.
function init() {
    ctx = canvas.getContext("2d");

    render();
}

-1

我也遇到了这个问题。但是经过一番尝试,我发现调整画布元素的大小会自动清除画布上的所有绘图!只需尝试下面的代码

<canvas id = 'canvas'></canvas>
<script>
    var canvas1 = document.getElementById('canvas')
    console.log('canvas size',canvas1.width, canvas1.height)
    var ctx = canvas1.getContext('2d')
    ctx.font = 'Bold 48px Arial'
    var f = ctx.font
    canvas1.width = 480
    var f1 = ctx.font
    alert(f === f1) //false
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接