Canvas Shadow

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
shadowColorUse rgba for transparency
shadowBlurHigher = softer shadow
shadowOffsetX/YMoves shadow relative to shape
save() / restore()Avoid leaking styles
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.
Tip: Use semi-transparent shadows (rgba) for more natural depth. Very high blur values can be expensive to render in animations.
Rectangle Shadow (Legacy-Style Example)
Set shadow properties, then draw a filled rectangle.
<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>Apply Shadow to Only One Shape (save/restore)
Use save()/restore() to prevent shadow from affecting later drawings.
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
shadowBlur or offsets are non-zero. Shadows only appear on drawings after you set the properties.save()/restore() so later drawings don’t inherit shadow settings.Next: Canvas States
Learn how save() and restore() help you manage styles, shadows, and transforms.
4 people found this page helpful
