2D Drawing with
<canvas>
Some of my other canvas creations
Sunscreen
Mandalatron
What's a 2D canvas?
- A grid of pixels
- A set of drawing stateful APIs for painting
- rectangles
- circles
- shapes and curves
- images and gradients
- text
- Fast!
- Animatable!
- Consistent in conceptual approach on many platforms
The basics
(in Web Browser Javascript)
// HTML
<canvas
id="canvas"
width="500"
height="500"
/>
// JS
let canvas = document.getElementById('canvas')
let ctx = canvas.getContext('2d')
Rectangles
with fills and strokes
ctx.fillStyle = 'red'
ctx.fillRect(50, 50, 100, 100)
ctx.strokeStyle = '#00ff00'
ctx.lineWidth = 5
ctx.strokeRect(200, 50, 100, 100)
ctx.fillStyle = 'rgba(255,255,255, 0.25)'
ctx.fillRect(350, 50, 100, 100)
Paths
connecting vertices
ctx.fillStyle = 'red'
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(150, 50)
ctx.lineTo(150, 150)
ctx.closePath()
ctx.fill()
Circles & Arcs
x, y, r, start, end
ctx.beginPath()
ctx.arc(100, 100, 50, 0, 2 * Math.PI)
ctx.fill()
ctx.beginPath()
ctx.arc(250, 100, 50, 0, 1 * Math.PI)
ctx.fill()
ctx.beginPath()
ctx.arc(400, 100, 50, 0, 0.5 * Math.PI)
ctx.fill()
Animate
Clear, Draw, Repeat
const speed = 100 // per second
function draw(elapsed) {
let seconds = elapsed / 1000
let x = seconds * speed % 400
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, 50, 100, 100)
requestAnimationFrame(draw)
}
requestAnimationFrame(draw)
The Context
A singular and stateful collection of all your drawing settings
Singular and Stateful
const ctx = canvas.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(0,0,10,10) // red
ctx.fillRect(10,0,10,10) // red
ctx.fillRect(20,0,10,10) // red
ctx.fillStyle = 'blue'
ctx.fillRect(30,0,10,10) // blue
Settings are remembered for all drawing functions until changed.
Space is stateful, too!
Move the origin around
function drawSquare() {
ctx.fillRect(50, 50, 100, 100)
}
drawSquare()
ctx.translate(150, 0)
drawSquare()
ctx.translate(150, 0)
drawSquare()
save(), restore()
function drawSquare(x, y) {
ctx.save() // stash a snapshot of unaltered context
ctx.translate(x, y) // alter the context
ctx.fillRect(0, 0, 100, 100) // draw something
ctx.restore() // undo all context changes since last save()
}
drawSquare(50, 50)
drawSquare(200, 50)
drawSquare(350, 50)
Canvas Transformations
Solar System
function drawCelestialBody(r, dist, color) {
ctx.save()
// orbital speed is a function of distance
let orbitSpeed = 1 / Math.pow(dist, 2)
// Rotate around
ctx.rotate(elapsed * orbitSpeed * SPEED)
// Move "UP" from the center
ctx.translate(0, dist)
// Draw the celestial body at the origin
ctx.beginPath()
ctx.arc(
0, 0, // x, y
r, // radius
0, 2 * Math.PI // full circle
)
// Set the color and fill it in!
ctx.fillStyle = color
ctx.fill()
crx.restore()
}
Starlit Breeze
Starlit Breeze: Techniques
-
Stars
- Store array of randomized points
- Slowly rotate the sky context
-
Moon
- rotate moon context faster than stars
- Draw circle off center
-
Tree
- recursively, to a certain depth, do:
- ctx.save()
- Draw a rectangle
- Move "up" context
- Rotate context, with a bit of time based variation
- Scale down context, just a little
- If at max depth draw a red circle at origin (which will be branch tip)
- ctx.restore()
- recursively, to a certain depth, do:
2D Drawing with Canvas
By Alex Wayne
2D Drawing with Canvas
- 523