I have been trying this simple animation with html 5 and javascript from here:
http://www.developphp.com/view.php?tid=1262
The code is follwoing:
<!-- Lesson by Adam Khoury # www.developphp.com -->
<!-- Watch the video to get code explanation line by line -->
<!-- http://www.youtube.com/watch?v=hUCT4b4wa-8 -->
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
canvas{border:#666 1px solid;}
</style>
<script type="text/javascript">
function draw(x,y){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(0,0,550,400);
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect (x, y, 50, 50);
ctx.restore();
x += 1;
var loopTimer = setTimeout('draw('+x+','+y+')',100);
}
</script>
</head>
<body>
<button onclick="draw(0,0)">Draw</button>
<canvas id="canvas" width="550" height="400"></canvas>
</body>
</html>
There is just one thing i don't understand in the code: in the setTimeout method what does the '+' before and after x and y do and why quotes are used to enclose +x+ and +y+?
'draw('+x+','+y+')' This is a just string concatination you will understand this by printing that string. following fiddle explains more.
http://jsfiddle.net/zebqqcee/
The setTimeout will execute the instruction with an eval, I mean this will execute when the timeout pop this:
eval('draw('+x+','+y+')');
If you don't like this syntax, I personally don't, you can use this:
var loopTimer = setTimeout(function() {
draw(x,y);
},100);
Related
I have recently started working with Paper.js . Trying to use javascript directly i can't figure out why code below produces absolutely nothing when its running:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>paper1</title>
<script type="text/javascript" src="js/paper.js"></script>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("myCanvas");
paper.setup(canvas);
var path = new paper.Path();
path.strokeColor = 'black';
var tool = new paper.Tool();
tool.onMouseDown = function(event) {
path.add(event.point);
}
paper.view.draw();
};
</script>
</head>
<body>
<canvas id="myCanvas" resize></canvas>
</body>
I would appreciate any idea
UPDATE
It works when i remove window.onload. Why is that happen?
Actually, something does show up. Try to click on the uper left most area of the canvas and the lines will show up. But if you click more on the bottom right, you will see that the lines are not added were you click but are shifted.
There seems to be a problem when using the resize attribute. Remove it and add the dimensions manually and it will work as inteded:
<canvas id="myCanvas" width="500" height="300"></canvas>
This is an interesting problem to me. The code below will work if I have code at the top of the page in the Head section. But the code will not work if I have the code at the bottom of the page. Why is this. I should be able to move the code around and it should work the same I would think. Because the Java Script when it is above in the Head part it will check to see if the page is loaded with the Action Listener. So if I put it at the bottom of the page (script) it will load the page first and then run my scripting code.
I want to put this at the bottom of the page to see how it will work at the bottom of the page as well. I should be able to take out the action listener with the load action that carries the script.
Code:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ch2Ex9 Rotation Transformation #3</title>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvas" width="500" height="500">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasApp(){
var theCanvas = document.getElementById('canvas');
if (!theCanvas || !theCanvas.getContext) {
return;
}
var context = theCanvas.getContext('2d');
if (!context) {
return;
}
drawScreen();
function drawScreen() {
//draw black square
context.fillStyle = "black";
context.fillRect(20,20 , 25, 25);
//now draw a red square
context.setTransform(1,0,0,1,0,0);
var angleInRadians =45 * Math.PI / 180;
var x=100;
var y=100;
var width=50;
var height=50;
context.translate(x+.5*width, y+.5*height);
context.rotate(angleInRadians);
context.fillStyle = "red";
context.fillRect(-.5*width,-.5*height , width, height);
}
}
</script>
</body>
</html>
Code (Works):
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ch2Ex9 Rotation Transformation #3</title>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasApp(){
var theCanvas = document.getElementById('canvas');
if (!theCanvas || !theCanvas.getContext) {
return;
}
var context = theCanvas.getContext('2d');
if (!context) {
return;
}
function drawScreen() {
//draw black square
context.fillStyle = "black";
context.fillRect(20,20 , 25, 25);
//now draw a red square
context.setTransform(1,0,0,1,0,0);
var angleInRadians =45 * Math.PI / 180;
var x=100;
var y=100;
var width=50;
var height=50;
context.translate(x+.5*width, y+.5*height);
context.rotate(angleInRadians);
context.fillStyle = "red";
context.fillRect(-.5*width,-.5*height , width, height);
}
drawScreen();
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvas" width="500" height="500">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
</body>
</html>
the bottom code works in the bottom example and that is because it checks and loads the page first and then runs the script. I should be able to move this to the bottom of the HTML page and remove the code that checks the load of the page and just call my two methods at the bottom of the script language.
Don't know if I'm stating the obvious here, but your top code you have left the closing </script> tag in the head, and it is missing from end of the script below it. Removing this from the head and adding it to the end of the page makes its work fine for me, both ways. Just so you know, I saw this in the Console of the browser (F12)
I have just started learning how to draw on using HTML5 canvas, I'm trying to make a simple square but all I get is a blank screen, I don't get errors in the chrome console either
<!Doctype html>
<html>
<head>
<title>Drawing to a canvas</title>
<script type="text/javascript" language="javascript" >
window.onload = draw;
function draw()
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect = (36,10,50,50);
}
</script>
</head>
<body>
<canvas id="canvas1" width="400" height="300">
This text is displayed if your browser
does not support HTML5 Canvas.
</canvas>
</body>
</html>
This seems quite simple but it just won't work for me!
One error is the one Elon pointed out, but you are using the fillRect wrong as well:
ctx.fillRect = (36,10,50,50);
should be:
ctx.fillRect(36,10,50,50);
Please debug before asking for help!
You've got syntax error because you forgot about { after function name.
function draw() {
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgba(0,200,0,1)";
ctx.fillRect(36,10,50,50);
}
I am failing at getting a DOM Image onclick event to work.
var context = document.getElementById('canvas').getContext('2d');
var image = new Image();
image.src = "foo.png"
image.onclick = function(e) { console.log("clicked"); }
setInterval(function() {
context.drawImage(image, 100, 100, 50, 50);
};
Why do I not get the log message when i click on the image. In developer tools i can see the onclick function is not null for the image.
Yes, what Musa said...and a few other things.
Some changes to your code
Image.src=”foo.png” should come after the image.onclick function
Context.drawImage should be inside the image.onclick function
setInterval is not needed as far as I can see
Try this:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var context=document.getElementById("canvas").getContext("2d");
var image=new Image();
image.onload=function(){
context.drawImage(image,0,0);
}
image.src="http://i.imgur.com/nJiIJIJ.png";
document.getElementById("canvas").addEventListener("click", function(){console.log("clicked");}, false);
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
You cannot set onclick for a particular image added in canvas . You can set onclick for the whole canvas alone so you have to use any third party js or else you should do some calculations which finds that you clicked on the image of the canvas ..
Other users are right.
The image you draw on the canvas is a DOM element but it is rendered in a position which is not stored in the DOM.
This doesn't mean you can access it's position and compare it with the mouse position.
I'm using an external library here, but it does what you need: http://jsfiddle.net/Saturnix/cygUH/
this is the library used.
Since I can't post link to jsfiddles without posting the code, here's the script I've wrote for you.
function demo(g) {
g.ctx.font = "bold 16px Arial";
g.draw = function () {
g.ctx.clearRect(0, 0, g.width, g.height)
var posX = 0;
var posY = 0;
g.ctx.drawImage(image, posX, posY);
if (g.mouseX > posX && g.mouseX < image.width &&
g.mouseY > posY && g.mouseY < image.height &&
g.mousePressed)
g.ctx.fillText("You're clicking the image!", g.mouseX, g.mouseY);
}
}
You can cast a ray (with an onclick on the canvas) into the canvas and manually test your images for intersection with the ray. You should write a
objectsUnderPoint( x, y );
function that returns an array of all the images that intersect with the ray at x, y.
This is the way it is usually done in 3D engines as well. You ofcourse need to keep the image position as a property of the image for intersection testing.
I'm trying to create a basic strobe light in the browser using the canvas element. I'm expecting setInterval to keep calling the changeBG function to change to a random background color. This function works fine on its own, but not when called by setInterval. I tried pulling up this page in firebug and it told me that colors was undefined. Here's the problematic code.
<html>
<head>
<title>Strobe!</title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript">
function changeBG(colors,ctx,canvas) {
ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)]
ctx.fillRect(0,0,canvas.width,canvas.height)
}
function eventLoop() {
var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']
var canvas = document.getElementById('mainCanvas')
var ctx = canvas.getContext('2d')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
//changeBG(colors,ctx,canvas)
setInterval("changeBG(colors,ctx,canvas)", 1000);
}
</script>
</head>
<body onload="eventLoop()">
<canvas id="mainCanvas" width="800" height="600">
</canvas>
</body>
I'm new to javascript so any insight what so ever would be highly appreciated.
You code would work if you weren't passing a string to setInterval. Because it is in a string, it can't create a closure on the variables you are trying to use.
Try this instead:
setInterval(function() {
changeBG(colors,ctx,canvas);
}, 1000);
Using this method, you are passing an anonymous function to setInterval. It will call this function once per interval, which is 1000 miliseconds in this example.
The function can use the colors, ctx, and canvas variables because they exist in the scope where the function is declared. This creates a closure so that those variables still exist (as far as our anonymous function is concerned) when it is called over and over again.
For now, you can probably just use this code. For further understanding, I suggest researching anonymous functions and closures.
You can pass directly a function, instead of a string to evaluate, as
setInterval(function(){changeBG(colors,ctx,canvas)}, 1000);
Good luck provoking epilepsy to someone
The root problem is variable scope when the interval code is executed, colors and the other variables are not in scope.
Try this:
<html>
<head>
<title>Strobe!</title>
<link rel="stylesheet" type="text/css" href="reset.css" />
<script type="text/javascript">
function eventLoop() {
var colors = ['#000000','#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']
var canvas = document.getElementById('mainCanvas')
var ctx = canvas.getContext('2d')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
setInterval(function() {
ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)]
ctx.fillRect(0,0,canvas.width,canvas.height)
}, 1000);
}
</script>
</head>
<body onload="eventLoop()">
<canvas id="mainCanvas" width="800" height="600">
</canvas>
</body>
try this
UPDATED
setInterval(function(){changeBG(colors,ctx,canvas)}, 1000);