Canvas Draw Paths

Beginner
⏱️ 10 min read
📚 Updated: Aug 2025
🎯 Live + 2 Examples
Path Commands

What You’ll Learn

A canvas path is a list of drawing commands you build up on the 2D context. You can then render that path with stroke() (outline) and/or fill() (interior).

Paths are how you build triangles, polygons, icons, charts, and many custom shapes.

⚡ Quick Reference

Path workflow
ctx.beginPath();
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.closePath(); // optional

ctx.fill();   // optional
ctx.stroke(); // optional
Start beginPath()

Begin a new shape

Move moveTo()

Position the pen without drawing

Draw lineTo()

Add a straight segment

Close closePath()

Connect back to the start

👀 Live Preview — Fill vs Stroke

Pick a shape and toggle fill() and stroke(). Notice how closePath() changes the outline and the filled area.

triangle · fill+stroke · closed

Tip: If you only call stroke(), an open path is fine. But for fill(), closing the shape often produces the expected result.

1

Triangle Path (Stroke)

A triangle is just a path with three points. Close it to connect the last point back to the start.

script.js
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.lineTo(100, 150);
ctx.closePath();

ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.stroke();
2

Fill + Stroke (Common Pattern)

Many UI-style shapes use fill + stroke. Fill first, then stroke so the outline stays crisp.

script.js
ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.beginPath();
ctx.moveTo(70, 160);
ctx.lineTo(220, 80);
ctx.lineTo(320, 200);
ctx.closePath();

ctx.fillStyle = 'rgba(37, 99, 235, 0.25)';
ctx.fill();

ctx.strokeStyle = '#0f172a';
ctx.lineWidth = 4;
ctx.stroke();

💡 Best Practices

Do

  • Start each shape with beginPath()
  • Use closePath() for closed shapes (especially before fill())
  • Fill first, then stroke for clean outlines
  • Use save()/restore() when changing many styles
  • Break complex drawings into multiple paths for clarity

Don’t

  • Forget that paths are stateful (the current point matters)
  • Accidentally continue an old path without calling beginPath()
  • Expect moveTo() to draw (it only moves the pen)
  • Assume open shapes will fill how you intend
  • Overdraw large canvases every frame without profiling

❓ Frequently Asked Questions

A path is a list of drawing commands. You render it using stroke() and/or fill().
It starts a new independent path so you don’t accidentally connect to previous shapes.
stroke() draws the outline; fill() paints the interior. You can do both.
Not always. But for closed shapes (and most fills) it helps produce the expected result by connecting back to the start point.

Next: Quadratic Curves

After straight paths, learn how to curve them smoothly.

Canvas Draw Quadratic →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

4 people found this page helpful