Canvas Shadow

Beginner
⏱️ 9 min read
📚 Updated: Aug 2025
🎯 Live + 2 Examples
Depth

What You’ll Learn

Canvas shadows add depth and realism to shapes, text, and images. Shadows are controlled by 4 properties: shadowColor, shadowBlur, shadowOffsetX, and shadowOffsetY.

These properties affect anything you draw afterward, so scoping them with save()/restore() is important.

⚡ Quick Reference

Color shadowColor

Use rgba for transparency

Softness shadowBlur

Higher = softer shadow

Offset shadowOffsetX/Y

Moves shadow relative to shape

Scope it save() / restore()

Avoid leaking styles

Shadow properties
ctx.shadowColor = 'rgba(0, 0, 0, 0.35)';
ctx.shadowBlur = 12;
ctx.shadowOffsetX = 6;
ctx.shadowOffsetY = 8;

👀 Live Preview — Shadow Controls

Adjust shadow blur and offsets and see how they affect a shape and text. This preview also shows why scoping matters by drawing a second element without shadow.

blur 14 · offset 8,10

Tip: Use semi-transparent shadows (rgba) for more natural depth. Very high blur values can be expensive to render in animations.

1

Rectangle Shadow (Legacy-Style Example)

Set shadow properties, then draw a filled rectangle.

index.html
<canvas id="myCanvas" width="240" height="200"></canvas>
<script>
  const canvas = document.getElementById('myCanvas');
  const ctx = canvas.getContext('2d');

  ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
  ctx.shadowBlur = 10;
  ctx.shadowOffsetX = 5;
  ctx.shadowOffsetY = 5;

  ctx.fillStyle = 'blue';
  ctx.fillRect(50, 40, 120, 100);
</script>
2

Apply Shadow to Only One Shape (save/restore)

Use save()/restore() to prevent shadow from affecting later drawings.

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

ctx.save();
ctx.shadowColor = 'rgba(0, 0, 0, 0.35)';
ctx.shadowBlur = 14;
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 10;
ctx.fillStyle = '#2563eb';
ctx.fillRect(40, 40, 160, 110);
ctx.restore();

// This one has no shadow
ctx.fillStyle = '#0f172a';
ctx.fillRect(240, 70, 90, 80);

💡 Best Practices

Do

  • Use rgba shadows (semi-transparent) for natural depth
  • Scope shadows with save()/restore()
  • Keep blur values reasonable (large blur can be slow)
  • Use subtle offsets for UI-like drop shadows
  • Cache expensive shadowed drawings on an offscreen canvas when animating

Don’t

  • Forget that shadow properties persist for future drawings
  • Use fully opaque black shadows for everything (looks harsh)
  • Animate huge shadows on large canvases without profiling
  • Expect shadow properties to affect only one draw call automatically
  • Ignore that offsets are in canvas pixels and scale with transforms

❓ Frequently Asked Questions

Make sure your shadow isn’t fully transparent, and that shadowBlur or offsets are non-zero. Shadows only appear on drawings after you set the properties.
Yes. Shadows affect fills, strokes, and text while the shadow properties are set.
Wrap the shadow drawing in save()/restore() so later drawings don’t inherit shadow settings.
They can be. High blur on large canvases in animation loops is expensive. Cache shadowed results if needed.

Next: Canvas States

Learn how save() and restore() help you manage styles, shadows, and transforms.

Canvas States →

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