Why I can't clear a canvas with another empty canvas in HTML5?
up vote
3
down vote
favorite
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);`
})
Like the code above, when using an empty canvas to clear another canvas, it's not working. (HTML only with <canvas id="canvas"></canvas>
tag). Live Demo on https://jsfiddle.net/wjvtzng7/
javascript html html5 canvas html5-canvas
|
show 2 more comments
up vote
3
down vote
favorite
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);`
})
Like the code above, when using an empty canvas to clear another canvas, it's not working. (HTML only with <canvas id="canvas"></canvas>
tag). Live Demo on https://jsfiddle.net/wjvtzng7/
javascript html html5 canvas html5-canvas
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
HTML5 only allow onecanvas
instance?
– sabertazimi
yesterday
buffer
andcanvas
refer to different<canvas>
instances in above code
– sabertazimi
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
2
fillRect
doesn't truly clearbuffer
andcanvas
(It works inline 14
too).
– sabertazimi
yesterday
|
show 2 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
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);`
})
Like the code above, when using an empty canvas to clear another canvas, it's not working. (HTML only with <canvas id="canvas"></canvas>
tag). Live Demo on https://jsfiddle.net/wjvtzng7/
javascript html html5 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);`
})
Like the code above, when using an empty canvas to clear another canvas, it's not working. (HTML only with <canvas id="canvas"></canvas>
tag). Live Demo on https://jsfiddle.net/wjvtzng7/
javascript html html5 canvas html5-canvas
javascript html html5 canvas html5-canvas
asked yesterday
sabertazimi
274
274
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
HTML5 only allow onecanvas
instance?
– sabertazimi
yesterday
buffer
andcanvas
refer to different<canvas>
instances in above code
– sabertazimi
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
2
fillRect
doesn't truly clearbuffer
andcanvas
(It works inline 14
too).
– sabertazimi
yesterday
|
show 2 more comments
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
HTML5 only allow onecanvas
instance?
– sabertazimi
yesterday
buffer
andcanvas
refer to different<canvas>
instances in above code
– sabertazimi
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
2
fillRect
doesn't truly clearbuffer
andcanvas
(It works inline 14
too).
– sabertazimi
yesterday
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
HTML5 only allow one
canvas
instance?– sabertazimi
yesterday
HTML5 only allow one
canvas
instance?– sabertazimi
yesterday
buffer
and canvas
refer to different <canvas>
instances in above code– sabertazimi
yesterday
buffer
and canvas
refer to different <canvas>
instances in above code– sabertazimi
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
2
2
fillRect
doesn't truly clear buffer
and canvas
(It works in line 14
too).– sabertazimi
yesterday
fillRect
doesn't truly clear buffer
and canvas
(It works in line 14
too).– sabertazimi
yesterday
|
show 2 more comments
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
If we write down what you are doing, we get:
One offscreen canvas "buffer", and one visible canvas "screen".
Step by step,
draw a circle on "buffer"
At this stage
- "buffer" represents a circle,
- "screen" represents an empty image (transparent pixels).
draw "buffer" on "screen" canvas
- "buffer" represents a circle,
- "screen" represents a circle
clear "buffer"
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
draw "buffer" on "screen" canvas
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
It seems your confusion comes from the last bullet. But this operation could be rewritten as
- draw an empty image (transparent pixels) to an image that represents a circle.
This indeed does nothing... at least in normal compositing mode source-over where drawing a fully transparent pixel does nothing. See alpha-compositing for more reads about it.
So if you wish to clear your "screen" canvas, you indeed need to clear it using the clearRect()
method of the screen
context. There are other ways, but don't use them.
Now, I felt I should also point out that there are other compositing modes than source-over available, and that what you expected can actually be done with one of these: 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>
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
If we write down what you are doing, we get:
One offscreen canvas "buffer", and one visible canvas "screen".
Step by step,
draw a circle on "buffer"
At this stage
- "buffer" represents a circle,
- "screen" represents an empty image (transparent pixels).
draw "buffer" on "screen" canvas
- "buffer" represents a circle,
- "screen" represents a circle
clear "buffer"
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
draw "buffer" on "screen" canvas
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
It seems your confusion comes from the last bullet. But this operation could be rewritten as
- draw an empty image (transparent pixels) to an image that represents a circle.
This indeed does nothing... at least in normal compositing mode source-over where drawing a fully transparent pixel does nothing. See alpha-compositing for more reads about it.
So if you wish to clear your "screen" canvas, you indeed need to clear it using the clearRect()
method of the screen
context. There are other ways, but don't use them.
Now, I felt I should also point out that there are other compositing modes than source-over available, and that what you expected can actually be done with one of these: 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>
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
add a comment |
up vote
1
down vote
accepted
If we write down what you are doing, we get:
One offscreen canvas "buffer", and one visible canvas "screen".
Step by step,
draw a circle on "buffer"
At this stage
- "buffer" represents a circle,
- "screen" represents an empty image (transparent pixels).
draw "buffer" on "screen" canvas
- "buffer" represents a circle,
- "screen" represents a circle
clear "buffer"
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
draw "buffer" on "screen" canvas
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
It seems your confusion comes from the last bullet. But this operation could be rewritten as
- draw an empty image (transparent pixels) to an image that represents a circle.
This indeed does nothing... at least in normal compositing mode source-over where drawing a fully transparent pixel does nothing. See alpha-compositing for more reads about it.
So if you wish to clear your "screen" canvas, you indeed need to clear it using the clearRect()
method of the screen
context. There are other ways, but don't use them.
Now, I felt I should also point out that there are other compositing modes than source-over available, and that what you expected can actually be done with one of these: 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>
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
If we write down what you are doing, we get:
One offscreen canvas "buffer", and one visible canvas "screen".
Step by step,
draw a circle on "buffer"
At this stage
- "buffer" represents a circle,
- "screen" represents an empty image (transparent pixels).
draw "buffer" on "screen" canvas
- "buffer" represents a circle,
- "screen" represents a circle
clear "buffer"
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
draw "buffer" on "screen" canvas
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
It seems your confusion comes from the last bullet. But this operation could be rewritten as
- draw an empty image (transparent pixels) to an image that represents a circle.
This indeed does nothing... at least in normal compositing mode source-over where drawing a fully transparent pixel does nothing. See alpha-compositing for more reads about it.
So if you wish to clear your "screen" canvas, you indeed need to clear it using the clearRect()
method of the screen
context. There are other ways, but don't use them.
Now, I felt I should also point out that there are other compositing modes than source-over available, and that what you expected can actually be done with one of these: 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>
If we write down what you are doing, we get:
One offscreen canvas "buffer", and one visible canvas "screen".
Step by step,
draw a circle on "buffer"
At this stage
- "buffer" represents a circle,
- "screen" represents an empty image (transparent pixels).
draw "buffer" on "screen" canvas
- "buffer" represents a circle,
- "screen" represents a circle
clear "buffer"
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
draw "buffer" on "screen" canvas
- "buffer" represents an empty image (transparent pixels)
- "screen" represents a circle
- "buffer" represents an empty image (transparent pixels)
It seems your confusion comes from the last bullet. But this operation could be rewritten as
- draw an empty image (transparent pixels) to an image that represents a circle.
This indeed does nothing... at least in normal compositing mode source-over where drawing a fully transparent pixel does nothing. See alpha-compositing for more reads about it.
So if you wish to clear your "screen" canvas, you indeed need to clear it using the clearRect()
method of the screen
context. There are other ways, but don't use them.
Now, I felt I should also point out that there are other compositing modes than source-over available, and that what you expected can actually be done with one of these: 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>
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>
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>
answered yesterday
Kaiido
37.2k45295
37.2k45295
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
add a comment |
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
Awesome! Have learned compositing modes
– sabertazimi
19 hours ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53265265%2fwhy-i-cant-clear-a-canvas-with-another-empty-canvas-in-html5%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
In javaScript you only get a reference of your objects. if you have 2 of them, you have 2 exact the same object, if you change the one, then you changed the other too. That is the reason why your function not work like you think.
– episch
yesterday
HTML5 only allow one
canvas
instance?– sabertazimi
yesterday
buffer
andcanvas
refer to different<canvas>
instances in above code– sabertazimi
yesterday
No that was not what I meant. I mean in your JavaScript this is const buffer = document.createElement ('canvas'); const canvas = document.getElementById ('canvas'); takes care of the buffer and canvas are both references from the same canvas, all changes to buffer or canvas, directly affect both variables, which is just a reference of the objects in there.
– episch
yesterday
2
fillRect
doesn't truly clearbuffer
andcanvas
(It works inline 14
too).– sabertazimi
yesterday