Designing Interactivity
with HTML5 Canvas
What is this workshop about?
Using HTML5 Canvas to allow you to create dynamic, interactive interfaces on the Web
How we going to do that?
(a little) HTML, (a little more) jQuery & (a lot) JavaScript
Workshop overview
Today
-
What is Canvas
-
Getting Canvas up and running and drawing
-
Adding some Interactivity
-
Timers and loops
-
Drawing Images
-
Transforms
-
Particle Systems
-
Interactive Particle system
Tomorrow
-
Simple hit and collision detection
-
2D physics
-
Paper.js
-
Three.js
Where did it come from?
It came from Apple OSX Dashboard widgets
What is Canvas?
What does canvas let you do?
It let's you draw pixels onto the page. (2D)
What does 3D canvas let you do?
It let's you draw triangles in 3D (WebGL)
Some examples of Canvas
How is the support?
-
Firefox
-
Opera
-
Safari
-
Chrome
-
IE9
-
< IE8 with excanvas.js (slow and buggy)
How do we use it?
-
Add it on the page
-
Get the drawing context
-
Draw something onto it
1. Add it to the page.
Need to declare a HTML5 doctype, write some HTML, and add a Canvas tag with a width and a height.
2. Getting the rendering context
The context is actually what we use to draw on the page.
var canvas = document.getElementById('canvasElem');
var ctx = canvas.getContext && canvas.getContext('2d');
if(!ctx) {
// No 2d context available, let the user know
alert('Please upgrade your browser');
} else {
// Do something
}
3. Draw something
Use ctx.fillStyle ="COLOR" and ctx.fillRect(x,y,w,h) to draw some rectangles no the screen.
A Quick Note
From now on, we're just going to show the JavaScript. The last slide just becomes:
Actually we'll make it even shorter:
Using jQuery selector and putting the getContext on the same line.
Other stuff we can draw:
-
More rectangles
ctx.fillRect(x,y,width,height)
ctx.clearRect(x,y,width,height)
ctx.strokeStyle = "#000000";
ctx.strokeRect(x,y,width,height)
-
Lines
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x,y);
ctx.lineTo(x,y);
ctx.fill(); or ctx.stroke();
-
Arcs
ctx.beginPath();
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
ctx.fill(); or ctx.stroke();
-
Setting the opacity
ctx.globalAlpha = 0.2;
ctx.fillRect(x,y,width,height);
-
Draw a picture:
Snow man?
Where's the interactivity?
To get interactivity, we need to listen for events
Listening for events with JavaScript
Listening for events with jQuery
Once again, jQuery makes our life easier, and use $("elem").on(..) to bind with a consistent event object. (Make sure you have a 1.7 or higher version of jQuery)
what's in the event
Let's examine the event Object
Getting the X and Y
Let's examine the event Object (Open up the console)
Bad news: offsetX and offsetY aren't universally supported (WebKit only)
Workaround is to calc it yourself. We're going to skip this in these slides for simplicity's sake and
assume you are using Chrome to view this.
Draw a square
Draw a 4x4 square centered on the mouse cursor.
Draw a random color square
Drawing some lines
Draw use beginPath, moveTo, lineTo to draw lines on mousedown and mousemove.
What about the keyboard?
We can listen for keypress, keydown and keyup events
Listening for keyboard events
Listening the arrow keys
The arrow keys are sort of difficult to get at, as we need know the keycodes to get at them. Also the arrow keys don't send keypess events.
Drawing Circles under the keyboard
Drawing colored under the keyboard
What about animation?
To get animation, we need to switch from event-driven drawing to timer-driven drawing
Timers in JavaScript
-
setInterval - call repeatedly
function animationLoop() {
// Run some code
}
var loopTimer = setInterval(animationLoop,30);
-
setTimeout - call once
function animationLoop() {
// Run some code
loopTimer = setTimeout(animationLoop,30);
// pass a callback + # of milliseconds
}
var loopTimer = setTimeout(animationLoop,30);
-
clearInterval / clearTimeout
clearInterval(loopTimer);
// or
clearTimeout(loopTimer);
Which is best?
Neither - requestAnimationFrame, which works like setTimeout but let's the browser control the animation. But for now, use setTimeout
Animating Objects
-
Position based on velocity
x = x + vx * dt;
y = y + vy * dt;
-
Velocity based on acceleration
vx = vx + ax * dt;
vy = vy + ay * dt;
-
All to together now
vx += ax * dt;
vy += ay * dt;
x += vx * dt;
y += vy * dt;
Make a Ball fly through the air
Make a Ball fly through the air
Images
Canvas also let's you draw images
Need to have image objects first
-
Can pull the from the page:
<img src='images/penguin.png' id='penguin'/>
<script>
// Wait for page to finish loading
$(function() {
var img = $("#penguin")[0];
// Do something with img
});
</script>
-
Can load entirely in JavaScript
<script>
var img = new Image();
img.onload = function() {
// We can use image
}
img.src = 'images/penguin.png';
</script>
Drawing images on Canvas
-
Simplest, just pass an image and a x and y
ctx.drawImage(img,x,y);
-
Can also pass a destination width and height
ctx.drawImage(img,x,y,dw,dh);
-
Or at it's most complicated:
ctx.drawImage(img,sx,sy,sw,sh,dx,dy,dw,dh);
Let's exercise image drawing
Make an image stamper
Make the penguin follow the mouse
penguin vs. mouse *slowly*
Transforms
Pulsating Snowflake
Order is very important!
Particle System
-
A bunch of small objects that are animated and have some behavior and a lifetime
-
Can store them in an array
var particles = [];
-
Can create a particle object prototype to draw and update
var Particle = function() { /* Initialize */ }
Particle.prototype.update(ctx) { /* Update the particle */ }
Particle.prototype.draw(ctx) { /* Draw the particle */ }
-
Can just loop over all of them to update an draw
for(var i = 0, len = particle.length; i<len; i++) {
var particle = particles[i];
particle.update(dt);
particle.draw(ctx);
}
Particle Lifetime
If they have a lifestime, we need to handle removing them
removedParticles = [];
for(var i = 0, len = particle.length; i<len; i++) {
var particle = particles[i];
particle.update(dt);
if(particle.dead) { removedParticles.push(particle); }
particle.draw(ctx);
}
for(var k =0;k<removedParticles.length;k++) {
var idx = particle.indexOf(removedParticles[k]);
// If particle is found
if(idx != -1) {
particles.splice(idx,1);
}
}
Random Colored Twinkling Lights
Starfield
Turn the twinkling lights into a flying starfield
Putting it all together
-
Create a particle fountain
-
It should spout multicolor particles
-
Use the mouse position or mouse click.
-
Particles should spray at random angles and fall w/ gravity.
-