HTML5 Canvas animation clearRect - html

I just started HTML5. I have a problem making a line following the mouse. It works if I don't clearRect( if I remove the line context.clearRect(0, 0, canvas.width, canvas.height);). Any ideea? I attached the code. Thanks
<html>
<head>
<title>Test</title>
</head>
<body>
<canvas id="myCanvas" width="1000" height="600" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
window.onload = function()
{
};
function captureMousePosition(evt)
{
var c = document.getElementById("myCanvas");
var context = c.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeStyle = 'rgba(0,153,255,0.4)';
context.beginPath();
context.moveTo(0,0);
context.lineTo(evt.x, evt.y);
context.stroke();
}
document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = captureMousePosition;
</script>
</body>

context.clearRect(0, 0, canvas.width, canvas.height);
Will clear the complete canvas, thus erasing the line that was on the canvas so far.
One solution is to clear the canvas only once before you start drawing. For example, clear the canvas at the window.onLoad() event, and then only clear again when you start a new drawing.
A second solution would be to store every mouse movement in a long array and redraw that complete line every frame.
edit: update with regard to your clarification below. The code doesn't work due to a syntax error in the clearRect code. You use 'canvas' which is not defined.
context.clearRect(0, 0, c.width, c.height);
does the trick!

I have created a jsFiddle for your problem. To me the problem was in evt.x and evt.y, they were undefined. I have pasted my own functions to get mouse coordinates. You can use a simple way but this is the most reliable way.
http://jsfiddle.net/g9xQ2/

Related

Circle not showing while using Canvas

This is the code from a course in Udemy. I did not understand why circle is not showing up for me. The same code when used by the instructor produces a circle.
Rectangle works fine for me.
var canvas, canvasContext;
console.log("text from script");
window.onload = function() {
canvas = document.getElementById('gameCanvas');
canvasContext = canvas.getContext('2d');
canvasContext.fillStyle = "red";
canvasContext.fillRect(0, 0, canvas.width, canvas.height);
// cavasContext.fillStyle="white";
// canvasContext.beginPath();
// canvasContext.arc(100,100,10,0,Math.PI*2,true);
cavasContext.beginPath();
cavasContext.arc(100, 75, 50, 0, 2 * Math.PI);
cavasContext.stroke();
}
<canvas id="gameCanvas" width="800" height="600"></canvas>
There is a typo, you've spelled canvasContext wrong, missed a "n".
cavasContext.beginPath();
cavasContext.arc(100,75,50,0,2*Math.PI);
cavasContext.stroke();
Should probably be:
canvasContext.beginPath();
canvasContext.arc(100,75,50,0,2*Math.PI);
canvasContext.stroke();

HTML5-canvas. My drawing isn't smooth. I've tried everything

var canvas;
var context;
var isDrawing = false;
window.onload = function()
{
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
canvas.addEventListener("mousemove", putPoint);
canvas.addEventListener("mousedown", engage);
canvas.addEventListener("mouseup", disengage);
canvas.addEventListener("mouseout", disengage);
context.lineWidth = 2*radius;
context.lineJoin = context.lineCap = 'round';
};
var radius=0.5;
var engage = function(e)
{
isDrawing = true;
putPoint(e)
}
var disengage = function()
{
isDrawing = false;
context.beginPath();
}
var putPoint=function (e)
{
if(isDrawing)
{
context.lineTo(e.clientX-canvas.offsetLeft, e.clientY-canvas.offsetTop);
context.stroke();
context.beginPath();
context.arc(e.clientX-canvas.offsetLeft, e.clientY-canvas.offsetTop, radius, 0, Math.PI*2);
context.fill();
context.beginPath();
context.moveTo(e.clientX-canvas.offsetLeft, e.clientY-canvas.offsetTop);
}
}
body
{
margin: 2px;;
}
canvas
{
border: 1px solid black;
display:block;
}
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title> Drawing app </title>
<link href="style.css" rel="stylesheet">
<script src="script2.js"> </script>
</head>
<body>
<canvas id="canvas" width="1900" height="1000"> Your browser doesn't support canvas. </canvas>
</body>
</html>
This is my code. Please try draw something. You should see a lot of pixels.
It looks awful. I would like to line looked like this:https://sketch.io/sketchpad/. Please set there 1px and check it. It's beautiful, smooth line without pixels. I would like to achieve it.
Here is nice drawing: http://codepen.io/kangax/pen/zofsp.
But:
- Every time you draw a new path - > canvas is cleaning. It is caused by 26th line of code.
- When I delete it ( I mean 26th line of code ) drawing breaks :c
What I've tried?
-shadows
-gradients
-ctx.translate(0.5,0.5);
-bezier curve
And it doesen't work.
I suppose that beautiful lines I can obtain using this: ctx.clearRect(x1,y1,x2,y2).
But I have no ideas how to use it :c
I am going to create drawing app so I need smooth lines.
Mouse data is always a but rough and there are many ways that you can smooth it. The holy grail for line smoothing is a bezier fit, but I have yet to work out how to do that in real time.
The next best thing is optimising and smoothing the line to an appox fit..
Rather than write the answer out again see the following anwser https://stackoverflow.com/a/33882382/3877726
It provides a way to set the optimization and smoothing from none (sometimes you want the bumps and lumps) all the way to super smooth..

clearRect not working?

I am a very beginner web designer and I have two questions about this code.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#canvas1{border: #666 3px solid;}
</style>
<script type="application/javascript" language="javascript">
function draw (x,y){
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillstyle = "rgb (0,200, 0)";
ctx.fillRect(x, 20, 50, 50);
ctx.restore();
x += 5;
var loop = setTimeout('draw('+x+', '+y+')', 100);
}
</script>
</head>
<body>
<button onclick="draw(0,0)">Start</button>
<canvas id="canvas1" width="400" height="400"</canvas>
</body>
</html>
Why does the block always turn out black? and Why if I try to press start again, the clearRect function doesn’t work?
When you click start you are starting a new loop that runs parallel to the one already started and depending on which one executes first your canvas would be cleared and filled twice (or as many times you started the loop - the more the more pronounced the flicker will be).
You need a mechanism to prevent the loop from starting several times. One way is to use a flag. I would also suggest you refactor the code a bit separating the loop and the drawing:
Live demo here
/// put these outside, no need to re-allocate them each time
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var x = 0;
var isRunning = false;
/// all loop-related here:
function loop() {
/// call draw from inside the loop instead
draw(x, 0); /// you are never using y so I just set 0 here...
x += 5;
if (isRunning && x <= w) {
requestAnimationFrame(loop); /// this is a better alternative
//setTimeout(loop, 100); /// optionally, but not recommended
} else {
isRunning = false; /// box is outside visible area so we'll stop..
}
}
/// keep draw() "clean", no loop code in here:
function draw(x, y) {
/// no need for save/restore here...
ctx.clearRect(0, 0, w, h);
ctx.fillStyle = "rgb(0, 200, 0)";
ctx.fillRect(x, 20, 50, 50);
}
Your fillStyle was typed wrong, your rgb(... must be without space (as mentioned in the other answer - but it would only result in the fill style being black in this case), in addition you're missing a closing bracket for your canvas tag in the html.
To check for button clicks this is a more recommended way instead of inlining the JS in the html:
/// check for button clicks (start):
document.getElementById('start').addEventListener('click', function() {
if (!isRunning) { /// are we running? if not start loop
isRunning = true; /// set flag so we can prevent multiple clicks
x = 0; /// reset x
loop(); /// now we start the *loop*
}
}, false);
And in your html:
<button id="start">Start</button>
Now you can easily make a pause button:
<button id="stop">Stop</button>
and add this to the script:
document.getElementById('stop').addEventListener('click', function() {
isRunning = false;
}, false);
Because you need to use:
ctx.fillStyle = "rgb(0,200,0)";
with a capital 'S' and no space between 'rgb' and the opening bracket: http://jsfiddle.net/dtHjf/
Then, in terms of why pressing 'Start' multiple times causes the square to flicker, that's because each time you press it you're starting another animation loop, but without cancelling the old one, so that you've got multiple loops fighting with each other. If you make sure to cancel any pre-existing loop before you start a new one, you should be fine:
http://jsfiddle.net/dtHjf/2/
HTML:
<button id="startAnim">Start</button><br />
<canvas id="canvas1" width="400" height="400"></canvas>
JS:
var canvas = document.getElementById('canvas1'),
ctx = canvas.getContext('2d'),
loop;
function draw(x, y) {
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "rgb(0,200,0)";
ctx.fillRect(x, 20, 50, 50);
ctx.restore();
x += 5;
loop = setTimeout(function(){draw(x,y)}, 100);
}
document.getElementById('startAnim').onclick = function(){
clearTimeout(loop);
draw(0,0);
};
Also, this is unrelated to your problem, but you might want to take a look at requestAnimationFrame:
https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

HTML5 multiple canvas in a page

<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Animating Sprites In HTML5 Canvas | onlyWebPro.com</title>
</head>
<body>
<canvas id="myCanvas" width="100" height="100">
<!-- Insert fallback content here -->
Sorry, your browser doesn't support canvas technology
</canvas>
<script>
var width = 100,
height = 100,
frames = 4,
currentFrame = 0,
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
image = new Image()
image.src = 'sprite.png';
var draw = function(){
ctx.clearRect(0, 0, width, height);
ctx.drawImage(image, 0, height * currentFrame, width, height, 0, 0, width, height);
if (currentFrame == frames) {
currentFrame = 0;
} else {
currentFrame++;
}
}
setInterval(draw, 100);
</script>
</body>
</html>
The above is the code for creating a canvas which runs a sprite animation sequence in canvas.
Now I want to include another canvas image in same html. when i tried the old one gets replaced so please help me to create another canvas with another image.
Anyone solve it by providing a way to create a multiple canvas in a single HTML page
Add this at html part:
<canvas id="mySecondCanvas" width="100" height="100">
<!-- Insert fallback content here -->
Sorry, your browser still doesn't support canvas technology
</canvas>
And this how you get this canvas with javascript:
var second_canvas = document.getElementById("mySecondCanvas");
:)

clear canvas of multiuser HTML5 canvas

I'm trying to add a clear button to erase the canvas of union draw
I thought clearRect should be able to do that. I tried with:
function clearCanvas() {
clearRect(0,0,canvas.width,canvas.height);
}
or
function clearCanvas(x,y,w,h) {
ctx.clearRect(x,y,w,h);
}
...but it doesn't work, why?
The problem with using ctx.clearRect(0,0,canvas.width,canvas.height) is that if you have modified the transformation matrix you likely will not be clearing the canvas properly.
The solution? Reset the transformation matrix prior to clearing the canvas:
// Store the current transformation matrix
ctx.save();
// Use the identity matrix while clearing the canvas
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
ctx.restore();
Edit:
Chrome responds well to: context.clearRect ( x , y , w , h ); but IE9 seems to completely ignore this instruction.
IE9 seems to respond to: canvas.width = canvas.width; but it doesn't clear lines, just shapes, pictures and other objects.
So if you have a canvas and context created like this:
var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');
You can use a method like this:
function clearCanvas(context, canvas) {
context.clearRect(0, 0, canvas.width, canvas.height);
var w = canvas.width;
canvas.width = 1;
canvas.width = w;
}
Edit2:
use this code to check if the browser supports it:
function checkSupported() {
canvas = document.getElementById('canvas');
if (canvas.getContext){
ctx = canvas.getContext('2d');
// Canvas is supported
} else {
// Canvas is not supported
alert("We're sorry, but your browser does not support the canvas tag. Please use any web browser other than Internet Explorer.");
}
}
And to make this code execute when the web page loads, adjust the body tag so it reads like this:
<body onload="checkSupported();">