Circle not showing while using Canvas - html

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();

Related

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/

Context scaling breaks some drawing

I'm trying to draw on a virtual canvas of proportions 1x1 so that I don't have to constantly multiply out the actual dimensions.
This works perfectly when I draw circles, but it would appear as though it does not work well with rectangles, and I'm not sure why.
When I have the following code:
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.scale(this.canvas.width, this.canvas.height);
ctx.beginPath();
ctx.arc(.5, .5, .1, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
It works fine, and the circle scales with the canvas.
However, when I merely change it to the following:
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.scale(this.canvas.width, this.canvas.height);
ctx.fillStyle = "blue";
ctx.fillRect(0,0, .0001, .001);
ctx.beginPath();
ctx.arc(.5, .5, .1, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
the rectangle takes up the entirety of the screen and even covers up the circle, even though the circle is drawn after the rectangle. It should, obviously, be taking up a very minute amount of space on the canvas.
It might be worth noting that this occurs in a game loop.
However, the following works as expected, with a red circle appearing above a blue backdrop
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0,0, 50, 50);
ctx.beginPath();
ctx.arc(10, 10, 20, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
If you're calling this repeatedly in a game loop, the scale method will increase the scale of your transform, every time through the loop. So you end up with everything growing. Since you're not showing your actual code, it's hard to tell why the circle isn't affected.
Try calling scale() only once, or use save() and restore(), or just reset the transform at the start of the loop, before calling scale():
ctx.setTransform(1, 0, 0, 1, 0, 0);

HTML5 - I can't get the simplest of canvas elements to work. What am I doing wrong?

I'm interested in getting into HTML5 game dev, so naturally, one of the first things I went about was learning to use the canvas element. However, despite learning from well known sources and practically copy-pasting their code, I can't so much as draw a rectangle. Below is a sampling of my HTML and Javascript
<html>
<head>
<link rel="stylesheet" type="text/css" href="mainStyle.css">
<script src="mainScript.js"></script>
</head>
<body onload="draw();">
<canvas id="tut" width="300" height="200" style="border:1px solid #c3c3c3;"></canvas>
</body>
</html>
function draw(){
var c = document.getElementById("tut");
if(c.getContext){
var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(200, 0 , 0)";
ctx.fillRect(10, 10 55, 50);
ctx.fillStyle = "rgba(0, 0 200, 0.5)";
ctx.fillRect(30, 50, 55, 50)
}
}
Am I missing something here? Any help is appreciated.
Your draw function is outside the html block. It needs to be inside a script tag, for example
<script>
function draw(){
var c = document.getElementById("tut");
if(c.getContext){
var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(200, 0 , 0)";
// You were also missing a comma in this next line...
ctx.fillRect(10, 10, 55, 50);
// ...and also here.
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect(30, 50, 55, 50)
}
}
</script>

HTML5 CANVAS Shadow a bug? or a code defect?

I'm faced with the problem about drawing of canvas.
Canvas is saved to data:image once.
And it is made to redraw.
Two problems occur at this time.
A shadow will be applied to the object which has not drawn the shadow.
A shadow will become deep if save and a redraw are repeated.
<canvas id="SAMPLE" width="960" height="480"></canvas>
<script type="text/javascript" src="./jquery.js"></script>
<script>
var canvas = $("#SAMPLE"),
ctx = canvas[0].getContext("2d");
// first object (no shadow)
ctx.strokeStyle = "#0067ef";
ctx.fillStyle = "#0067ef";
ctx.lineCap = "round";
ctx.lineWidth = "15";
ctx.globalAlpha = 1;
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowColor = "#363636";
ctx.beginPath();
ctx.moveTo( 10, 10);
ctx.lineTo(200, 200);
ctx.stroke();
ctx.closePath();
// second object (has shadow)
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.shadowColor = "#363636";
ctx.beginPath();
ctx.moveTo(300, 10);
ctx.lineTo(400, 200);
ctx.stroke();
ctx.closePath();
// Canvas is saved to data:image once.
var save = canvas[0].toDataURL();
// clear canvas
ctx.clearRect(0, 0, 960, 480);
// redraw
var img = new Image();
img.src = save;
img.onload = function() {
ctx.drawImage(this,0,0);
};
</script>
It was normal when the picture at the time of save and before a redraw was investigated.
Two problems occur at the time of a redraw.
A shadow will be applied to the object which has not drawn the shadow.
A shadow will become deep if save and a redraw are repeated.
Does my code have a defect?
Because your fillStyle and other parameters are preserved, so upon drawing image, the effect is stacking up.
Use save() and restore() to prevent this:
ctx.save();
// first object (no shadow)
ctx.strokeStyle = "#0067ef";
ctx.fillStyle = "#0067ef";
/*
...
*/
ctx.closePath();
ctx.restore();
// Canvas is saved to data:image once.
JSFiddle demo with one extra canvas and the appended image for comparison.
Comment out the save() and restore() and re-run the fiddle, you'll notice the different.

HTML5 Canvas animation clearRect

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/