javascript - 为什么我不能在 HTML5 中用另一个空 Canvas 清除 Canvas ?

标签 javascript html canvas html5-canvas

const buffer = document.createElement('canvas');
const context = buffer.getContext('2d');
const canvas = document.getElementById('canvas');
const screen = canvas.getContext('2d');
// buffer canvas and screen canvas have same width and height

// draw a circle on buffer canvas
context.beginPath();
context.arc(50, 50, 10, 0, Math.PI * 2);
context.fillStyle = 'rgba(156, 39, 176,1)';
context.fill();

// render to screen canvas (working)
screen.drawImage(buffer, 0, 0);

// clear canvas when click
canvas.addEventListener('click', () => {
  context.clearRect(0, 0, buffer.width, buffer.height);
  screen.drawImage(buffer, 0, 0);   // not working
  // only working with `screen.clearRect(0, 0, canvas.width, canvas.height);`
})

像上面的代码,当使用一个空的 Canvas 来清除另一个 Canvas 时,它不起作用。 (仅带有 <canvas id="canvas"></canvas> 标签的 HTML)。在 https://jsfiddle.net/wjvtzng7/ 上进行现场演示

最佳答案

如果我们写下你正在做的事情,我们会得到:

一个屏幕外 Canvas “缓冲区”和一个可见 Canvas “屏幕”。

一步一步,

  • 在“缓冲区”上画一个圆
    在这个阶段
    • buffer”代表一个
    • screen”表示一个空图像(透明像素)
  • 在“屏幕” Canvas 上绘制“缓冲区
    • buffer”代表一个
    • screen”代表一个
  • 清除“缓冲区
    • 缓冲区”表示一个空图像(透明像素)
    • screen”代表一个圆
  • 在“屏幕” Canvas 上绘制“缓冲区
    • 缓冲区”表示一个空图像(透明像素)
    • screen”代表一个圆

您的困惑似乎来自最后一个项目符号。但是这个操作可以重写为

  • 绘制一个空图像(透明像素)到代表一个的图像。

这确实什么都不做...至少在正常的合成模式source-over中,绘制一个完全透明的像素什么都不做。参见 alpha-compositing有关它的更多信息。

所以如果你想清除你的“screen” Canvas ,你确实需要使用 screenclearRect() 方法来清除它> 上下文。 还有其他方法,但不要使用它们。



现在,我觉得我还应该指出还有其他 compositing modessource-over 可用,而且您所期望的实际上可以用其中之一完成:copy

const buffer = document.createElement('canvas');
const context = buffer.getContext('2d');
const canvas = document.getElementById('canvas');
const screen = canvas.getContext('2d');

// initialize
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
buffer.width = window.innerWidth;
buffer.height = window.innerHeight;
// draw a circle
context.beginPath();
context.arc(50, 50, 10, 0, Math.PI * 2);
context.fillStyle = 'rgba(156, 39, 176,1)';
context.fill();

// render to screen canvas
screen.drawImage(buffer, 0, 0);

// clear canvas when click
canvas.addEventListener('click', () => {
  context.clearRect(0, 0, buffer.width, buffer.height);
  // only the next drawing operation on screen will be visible
  // everything else will get cleared out
  screen.globalCompositeOperation = "copy";
  screen.drawImage(buffer, 0, 0);
  // set back to default mode
  screen.globalCompositeOperation = "sourc-over";
})
<canvas id="canvas"></canvas>

关于javascript - 为什么我不能在 HTML5 中用另一个空 Canvas 清除 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53265265/

相关文章:

javascript - this 关键字是构造函数中的 window 对象

javascript - 从移动设备调整到桌面后,菜单文本消失

javascript - HTML5 Canvas 鼠标

javascript - 带文字的 CSS 平行四边形

javascript - 如何将事件监听器结果输出到变量?

javascript - 如何随机化 Polymer 中 div 的显示顺序

javascript - 如何使用 Gatsby 在 Netlify 上获取多步骤表单

javascript - 为什么我的 CSS 不能在我的 Rails 应用程序上运行?

html - 之前使用 CSS 水平扩展 <tr> 元素的 border-top

android - 使用(整数)缩放尽可能快地绘制位图