javascript
217 lines · 1 tab
Alex Chang
Feb 2026
1 tab
// Get canvas and context
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 1. Basic shapes
// Rectangle (filled)
ctx.fillStyle = '#4285f4';
ctx.fillRect(10, 10, 100, 80); // x, y, width, height
// Rectangle (outline)
ctx.strokeStyle = '#ea4335';
ctx.lineWidth = 3;
ctx.strokeRect(130, 10, 100, 80);
// Clear rectangle
ctx.clearRect(15, 15, 90, 70);
// 2. Paths
ctx.beginPath();
ctx.moveTo(250, 50);
ctx.lineTo(300, 100);
ctx.lineTo(250, 150);
ctx.closePath();
ctx.fillStyle = '#34a853';
ctx.fill();
// 3. Circles and arcs
ctx.beginPath();
ctx.arc(380, 80, 40, 0, Math.PI * 2); // x, y, radius, startAngle, endAngle
ctx.fillStyle = '#fbbc04';
ctx.fill();
// Arc (partial circle)
ctx.beginPath();
ctx.arc(480, 80, 40, 0, Math.PI); // Half circle
ctx.strokeStyle = '#ea4335';
ctx.lineWidth = 2;
ctx.stroke();
// 4. Text
ctx.font = '24px Arial';
ctx.fillStyle = '#000';
ctx.fillText('Hello Canvas!', 10, 200);
ctx.strokeText('Outlined Text', 10, 240);
// Text alignment
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Centered', canvas.width / 2, canvas.height / 2);
// 5. Gradients
// Linear gradient
const linearGrad = ctx.createLinearGradient(0, 0, 200, 0);
linearGrad.addColorStop(0, '#4285f4');
linearGrad.addColorStop(1, '#34a853');
ctx.fillStyle = linearGrad;
ctx.fillRect(10, 300, 200, 100);
// Radial gradient
const radialGrad = ctx.createRadialGradient(330, 350, 10, 330, 350, 50);
radialGrad.addColorStop(0, '#fff');
radialGrad.addColorStop(1, '#4285f4');
ctx.fillStyle = radialGrad;
ctx.beginPath();
ctx.arc(330, 350, 50, 0, Math.PI * 2);
ctx.fill();
// 6. Images
const img = new Image();
img.onload = () => {
// Draw image
ctx.drawImage(img, 10, 450);
// Scale image
ctx.drawImage(img, 210, 450, 100, 100);
// Crop and scale
ctx.drawImage(
img,
0, 0, 100, 100, // source x, y, width, height
410, 450, 80, 80 // dest x, y, width, height
);
};
img.src = '/path/to/image.jpg';
// 7. Transformations
ctx.save(); // Save current state
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4); // 45 degrees
ctx.scale(1.5, 1.5);
ctx.fillStyle = '#ea4335';
ctx.fillRect(0, 0, 50, 50);
ctx.restore(); // Restore saved state
// 8. Compositing
ctx.globalAlpha = 0.5; // Transparency
ctx.globalCompositeOperation = 'multiply';
// 9. Shadows
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = '#4285f4';
ctx.fillRect(500, 300, 100, 80);
// Reset shadows
ctx.shadowColor = 'transparent';
// 10. Animation with requestAnimationFrame
let x = 0;
const ballRadius = 20;
const ballColor = '#4285f4';
function animate() {
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw ball
ctx.beginPath();
ctx.arc(x, canvas.height - 100, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = ballColor;
ctx.fill();
// Update position
x += 2;
if (x > canvas.width + ballRadius) {
x = -ballRadius;
}
requestAnimationFrame(animate);
}
animate();
// 11. Interactive canvas
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// Draw circle at click position
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI * 2);
ctx.fillStyle = '#ea4335';
ctx.fill();
});
// 12. Particle system
class Particle {
constructor(x, y) {
this.x = x;
this.y = y;
this.vx = (Math.random() - 0.5) * 4;
this.vy = (Math.random() - 0.5) * 4;
this.radius = Math.random() * 3 + 1;
this.alpha = 1;
}
update() {
this.x += this.vx;
this.y += this.vy;
this.alpha -= 0.01;
}
draw(ctx) {
ctx.save();
ctx.globalAlpha = this.alpha;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = '#4285f4';
ctx.fill();
ctx.restore();
}
isDead() {
return this.alpha <= 0;
}
}
const particles = [];
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
for (let i = 0; i < 3; i++) {
particles.push(new Particle(x, y));
}
});
function animateParticles() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = particles.length - 1; i >= 0; i--) {
const particle = particles[i];
particle.update();
particle.draw(ctx);
if (particle.isDead()) {
particles.splice(i, 1);
}
}
requestAnimationFrame(animateParticles);
}
animateParticles();
1 file · javascript
Explain with highlit
The Canvas API provides a drawable bitmap surface for graphics. I use <canvas> elements with 2D rendering context via getContext('2d'). Drawing methods include fillRect(), strokeRect(), arc(), and lineTo(). The save() and restore() methods manage drawing state. Transformations like translate(), rotate(), and scale() modify coordinates. The requestAnimationFrame() function creates smooth animations. Image manipulation uses drawImage() and getImageData(). Canvas excels at games, charts, and dynamic graphics. Understanding canvas enables rich visual experiences.
Related snips
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Semantic HTML Example</title>
Semantic HTML5 elements and accessibility best practices
html
html5
semantics
by Alex Chang
2 tabs
javascript
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
if (success) {
Promises and async/await patterns for asynchronous JavaScript
javascript
promises
async-await
by Alex Chang
1 tab
javascript
import { Controller } from "@hotwired/stimulus"
import Mousetrap from "mousetrap"
export default class extends Controller {
connect() {
// Global shortcuts
Keyboard shortcuts with Stimulus and Mousetrap
stimulus
javascript
ux
by Jordan Lee
2 tabs
javascript
// Basic event listener
const button = document.getElementById('myButton');
button.addEventListener('click', function(event) {
console.log('Button clicked!');
console.log('Event type:', event.type);
Event handling and event delegation patterns in JavaScript
javascript
events
event-delegation
by Alex Chang
1 tab
javascript
// Basic GET request
fetch('https://api.example.com/users')
.then(response => {
console.log('Status:', response.status);
console.log('OK:', response.ok);
return response.json();
Fetch API for HTTP requests and AJAX communication
javascript
fetch
api
by Alex Chang
1 tab
erb
<turbo-stream action="set_title">
<template><%= "Inbox (#{@unread_count})" %></template>
</turbo-stream>
Turbo Streams: update document title with a custom action
rails
hotwire
turbo
by Henry Kim
2 tabs
Share this code
Here's the card — post it anywhere.