The HTML5 <canvas> element allows you to draw complex shapes using paths.
Paths are sequences of points connected by lines or curves, which can be filled or outlined.
In this tutorial, you’ll learn how to:
- Create and use paths.
- Draw shapes with paths.
- Use curves and arcs.
- Combine and style paths.
1. Basics of Canvas Paths
To work with paths:
- Start a path: Use beginPath().
- Define the path: Use methods like moveTo, lineTo, and arc.
- Close the path (optional): Use closePath() to connect the last point to the starting point.
- Render the path:
- Use stroke() to draw the outline.
- Use fill() to fill the shape.
2. Drawing Basic Paths
Example 1: Creating a Triangle
<canvas id="myCanvas" width="500" height="300" style="border: 1px solid black;"></canvas> <script> const canvas = document.getElementById("myCanvas"); const ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(100, 50); // Starting point ctx.lineTo(200, 200); // Draw line to (200, 200) ctx.lineTo(50, 200); // Draw line to (50, 200) ctx.closePath(); // Close the path (connects back to start) ctx.strokeStyle = "blue"; // Outline color ctx.stroke(); // Render the outline ctx.fillStyle = "lightblue"; // Fill color ctx.fill(); // Fill the shape </script>
Explanation:
- moveTo(x, y): Moves the starting point of the path.
- lineTo(x, y): Draws a straight line to a point.
- closePath(): Closes the path by connecting the last point to the first.
3. Combining Multiple Paths
You can draw multiple paths within a single canvas.
Example 2: Drawing Overlapping Shapes
// First shape ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(150, 50); ctx.lineTo(100, 150); ctx.closePath(); ctx.fillStyle = "red"; ctx.fill(); // Second shape ctx.beginPath(); ctx.moveTo(150, 50); ctx.lineTo(250, 50); ctx.lineTo(200, 150); ctx.closePath(); ctx.fillStyle = "green"; ctx.fill();
4. Drawing Curves and Arcs
Paths can include curves and arcs for smoother and more complex shapes.
Example 3: Drawing Arcs
ctx.beginPath(); ctx.arc(150, 150, 50, 0, Math.PI * 2); // Full circle ctx.strokeStyle = "purple"; ctx.lineWidth = 2; ctx.stroke(); ctx.beginPath(); ctx.arc(300, 150, 50, 0, Math.PI); // Half circle ctx.strokeStyle = "orange"; ctx.stroke();
Explanation:
- arc(x, y, radius, startAngle, endAngle): Draws a circular or elliptical arc.
Example 4: Drawing a Quadratic Curve
ctx.beginPath(); ctx.moveTo(50, 200); // Starting point ctx.quadraticCurveTo(150, 50, 250, 200); // Control point and end point ctx.strokeStyle = "blue"; ctx.lineWidth = 2; ctx.stroke();
Explanation:
- quadraticCurveTo(cpX, cpY, x, y): Draws a quadratic Bezier curve with a control point.
Example 5: Drawing a Cubic Bezier Curve
ctx.beginPath(); ctx.moveTo(50, 250); ctx.bezierCurveTo(150, 50, 250, 400, 350, 250); // Two control points and end point ctx.strokeStyle = "green"; ctx.lineWidth = 2; ctx.stroke();
Explanation:
- bezierCurveTo(cp1X, cp1Y, cp2X, cp2Y, x, y): Draws a cubic Bezier curve with two control points.
5. Styling Paths
You can customize paths with styles, including:
- Line width: lineWidth
- Line color: strokeStyle
- Fill color: fillStyle
- Line joins and caps: lineJoin, lineCap
Example 6: Customizing Path Styles
ctx.beginPath(); ctx.moveTo(50, 100); ctx.lineTo(200, 50); ctx.lineTo(350, 100); ctx.lineJoin = "round"; // Options: bevel, round, miter ctx.strokeStyle = "black"; ctx.lineWidth = 5; ctx.stroke(); ctx.beginPath(); ctx.moveTo(50, 150); ctx.lineTo(200, 200); ctx.lineTo(350, 150); ctx.lineCap = "round"; // Options: butt, round, square ctx.strokeStyle = "blue"; ctx.lineWidth = 10; ctx.stroke();
6. Creating Complex Shapes
You can combine lines, arcs, and curves to create intricate designs.
Example 7: Drawing a Star
ctx.beginPath(); const centerX = 250; const centerY = 150; const spikes = 5; const outerRadius = 100; const innerRadius = 50; for (let i = 0; i < spikes * 2; i++) { const radius = i % 2 === 0 ? outerRadius : innerRadius; const angle = (i * Math.PI) / spikes; const x = centerX + Math.cos(angle) * radius; const y = centerY + Math.sin(angle) * radius; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.closePath(); ctx.strokeStyle = "gold"; ctx.fillStyle = "yellow"; ctx.lineWidth = 3; ctx.fill(); ctx.stroke();
7. Animating Paths
Example 8: Growing Path Animation
let progress = 0; function animatePath() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.beginPath(); ctx.moveTo(50, 150); ctx.lineTo(50 + progress, 150); ctx.strokeStyle = "blue"; ctx.lineWidth = 2; ctx.stroke(); if (progress < 400) { progress += 2; // Increment progress requestAnimationFrame(animatePath); } } animatePath();
8. Practical Example: Flower Design
Example 9: Flower with Arcs
const petals = 6; const centerX = 250; const centerY = 150; const radius = 100; for (let i = 0; i < petals; i++) { const angle = (i * 2 * Math.PI) / petals; ctx.beginPath(); ctx.arc(centerX + Math.cos(angle) * radius, centerY + Math.sin(angle) * radius, 50, 0, Math.PI * 2); ctx.fillStyle = i % 2 === 0 ? "pink" : "yellow"; ctx.fill(); }
9. Best Practices for Paths
- Use beginPath:
- Always start a new path with beginPath() to avoid unwanted connections.
- Close Paths:
- Use closePath() to create closed shapes easily.
- Optimize Complex Shapes:
- Combine lines, arcs, and curves for intricate designs.
- Save and Restore Context:
- Use save() and restore() to avoid overriding styles.
10. Browser Support
Paths are fully supported in all modern browsers:
Feature | Supported? |
---|---|
beginPath | Yes |
lineTo, moveTo | Yes |
arc, arcTo | Yes |
quadraticCurveTo | Yes |
bezierCurveTo | Yes |
11. Conclusion
In this tutorial, you learned:
- How to create and customize paths with lineTo, arc, and curves.
- How to style paths using colors, widths, and joins.
- Practical applications like stars, animations, and flowers.