javascript - 为什么我不能用 HTML5 中的另一个空画布清除画布?
问题描述
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 id="canvas"></canvas>
(仅带有标签的 HTML )。https://jsfiddle.net/wjvtzng7/上的现场演示
解决方案
如果我们写下你在做什么,我们会得到:
一个屏幕外画布“缓冲区”和一个可见画布“屏幕”。
一步步,
在这个阶段 在“缓冲区”上画一个圆圈- “缓冲区”代表一个圆圈,
- “屏幕”代表一个空图像(透明像素)。
- 在“屏幕”画布上绘制“缓冲区”
- “缓冲区”代表一个圆圈,
- “ screen ”代表一个圆圈
- 清除“缓冲区”
- “ buffer ”代表一个空图像(透明像素)
- “ screen ”代表一个圆圈
- 在“屏幕”画布上绘制“缓冲区”
- “ buffer ”代表一个空图像(透明像素)
- “ screen ”代表一个圆圈
看来您的困惑来自最后一个子弹。但是这个操作可以重写为
- 将空图像(透明像素)绘制到表示圆形的图像上。
这确实什么都不做......至少在正常合成模式下,绘制一个完全透明的像素什么都不做。有关它的更多信息,请参阅alpha-compositing。
所以如果你想清除你的“屏幕”画布,你确实需要使用上下文的clearRect()
方法来清除它。还有其他方法,但不要使用它们。screen
现在,我觉得我还应该指出,除了source-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 - 如何获取热门帖子 wordpress api wp-json v2
- python - 如何使用 xlwings 在 Excel 上以红色显示负值?
- cuda - 同一 GPU 的 MIG 之间的数据共享
- python - 使用具有多个条件、tres 日期和一个对象的 numpy/pandas 过滤 df
- tableau-api - Tableau - 每月客户总数
- javascript - 如何使用 %o 和 %O 使 Firefox 的控制台以不同的方式输出 dom 节点,就像 Chrome 所做的那样?
- objective-c - 模拟按键的代码不起作用,我在这里遗漏了什么吗?
- iis - 如何在经典 ASP 上设置默认内容页面?
- jquery - 使用 Rails 进行 Ajax 请求后无法获取 URL 参数
- java - 带有 URL 输入的 Android WebView