Reputation:
I'm in a web multimedia class and we are learning how to use html5's canvas and javascript to create interactivity in web pages. we are going over example programs from the book and I have been running through the code in my head in order to grasp it clearly. I'm having trouble with this current example: what I understand:
it uses a 'glasspane'
div to set a small menu above the actual canvas because apparently you have to use html controls outside of the canvas element, because it cannot run both the canvas .js
and the html controls.
in the .js
file:
What I don't understand:
startButton.onclick
.Code is below.
javascript:
var context = document.getElementById('canvas').getContext('2d'),
startButton = document.getElementById('startButton'),
glasspane = document.getElementById('glasspane'),
paused = true,
circles = [];
drawGrid(context, 'lightgray', 10, 10);
context.lineWidth = 0.5;
context.font = '32pt Arial';
for (var i=0; i < 100; ++i) {
circles[i] = {
x: 100,
y: 100,
velocityX: 3*Math.random(),
velocityY: 3*Math.random(),
radius: 50*Math.random(),
color: 'rgba(' + (Math.random()*255).toFixed(0) + ', ' +
(Math.random()*255).toFixed(0) + ', ' +
(Math.random()*255).toFixed(0) + ', 1.0)' };
}
startButton.onclick = function(e) {
e.preventDefault();
e.stopPropagation();
paused = ! paused;
startButton.innerText = paused ? 'Start' : 'Stop';
};
glasspane.onmousedown = function(e) {
e.preventDefault();
e.stopPropagation();
}
context.canvas.onmousedown = function(e) {
e.preventDefault();
e.stopPropagation();
};
setInterval(function() {
if (!paused) {
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
drawGrid(context, 'lightgray', 10, 10);
circles.forEach(function(circle) {
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI*2, false);
context.fillStyle = circle.color;
context.fill();
adjustPosition(circle);
});
}
}, 1000 / 60);
function adjustPosition(circle) {
if (circle.x + circle.velocityX + circle.radius > context.canvas.width ||
circle.x + circle.velocityX - circle.radius < 0)
circle.velocityX = -circle.velocityX;
if (circle.y + circle.velocityY + circle.radius > context.canvas.height ||
circle.y + circle.velocityY - circle.radius < 0)
circle.velocityY= -circle.velocityY;
circle.x += circle.velocityX;
circle.y += circle.velocityY;
}
function drawGrid(context, color, stepx, stepy) {
context.strokeStyle = color;
context.lineWidth = 0.5;
for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, context.canvas.height);
context.stroke();
}
for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {
context.beginPath();
context.moveTo(0, i);
context.lineTo(context.canvas.width, i);
context.stroke();
}
}
html:
<html>
<head>
<title>Bouncing Balls</title>
<style>
body {
background: #dddddd;
}
#canvas {
margin-left: 10px;
margin-top: 10px;
background: #ffffff;
border: thin solid #aaaaaa;
}
#glasspane {
position: absolute;
left: 50px;
top: 50px;
padding: 0px 20px 10px 10px;
background: rgba(0, 0, 0, 0.3);
border: thin solid rgba(0, 0, 0, 0.6);
color: #eeeeee;
font-family: Droid Sans, Arial, Helvetica, sans-serif;
font-size: 12px;
cursor: pointer;
-webkit-box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
-moz-box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
}
#glasspane h2 {
font-weight: normal;
}
#glasspane .title {
font-size: 2em;
color: rgba(255, 255, 0, 0.8);
}
#glasspane a:hover {
color: yellow;
}
#glasspane a {
text-decoration: none;
color: #cccccc;
font-size: 3.5em;
}
#glasspane p {
margin: 10px;
color: rgba(65, 65, 220, 1.0);
font-size: 12pt;
font-family: Palatino, Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<div id='glasspane'>
<h2 class='title'>Bouncing Balls</h2>
<p>One hundred balls bouncing</p>
<a id='startButton'>Start</a>
</div>
<canvas id='canvas' width='750' height='500'>
Canvas not supported
</canvas>
<script src='example.js'></script>
</body>
</html>
Upvotes: 0
Views: 65
Reputation: 106940
One way of exploring such code is experimenting with it. Try commenting parts of it out and see what happens.
Anyways, about your questions - I'm not sure why the onmousedown
handlers are there. They don't seem to do anything useful here. But maybe there is a point.
On the setInterval
function - it's not special. It just repeatedly executes the function which was passed to it. It tries to execute it once every 1000/60
milliseconds, which works out to 60 times a second.
(Mind you, in production code nobody uses setInterval
. Instead requestAnimationFrame
is the correct way to go; or if that's not available - at least setTimeout
. But that's a separate discussion and maybe you'll still get to that part in your class. Using setInterval
in an example would however make sense because it's simpler than the alternatives)
Note also that the function that was passed to setInterval
in this example has all it's contents wrapped in if (!paused) { ... }
- that's what's taking care of the pauses. When the animation is paused, the function still gets called, but it just doesn't do anything.
Upvotes: 1