Canvas Transform

What You’ll Learn
Canvas transforms modify the current transformation matrix (CTM). That matrix maps your drawing coordinates to pixels.
Once you understand transform order and how to reset state, you can position, rotate, and scale anything cleanly.
⚡ Quick Reference
ctx.translate(x, y);
ctx.rotate(angleRad);
ctx.scale(sx, sy);
// multiply current CTM
ctx.transform(a, b, c, d, e, f);
// replace CTM
ctx.setTransform(1, 0, 0, 1, 0, 0);moves originShift coordinate system
radiansRotate around origin
sx, syScale around origin
save/restoreSafest way to avoid leaks
👀 Live Preview — Combine Transforms
Play with translate, rotate, and scale. Switch transform order to see why it matters. The dashed box is the untransformed reference.
Rule of thumb: if you want to rotate/scale around a point, translate to that point first, then rotate/scale, then draw relative to (0,0), then restore.
Translate + Rotate (Legacy-Style Example)
Translate to the center, rotate, then draw centered around the origin.
<canvas id="myCanvas" width="200" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.translate(100, 100);
ctx.rotate(Math.PI / 4);
ctx.fillStyle = '#2563eb';
ctx.fillRect(-50, -50, 100, 100);
</script>Reset Transforms Safely
Use save/restore around transforms, or reset the CTM explicitly with setTransform.
ctx.save();
ctx.translate(200, 120);
ctx.rotate(Math.PI / 6);
ctx.scale(1.2, 1.2);
ctx.fillRect(-60, -40, 120, 80);
ctx.restore(); // CTM back to previous state
// Alternative reset:
ctx.setTransform(1, 0, 0, 1, 0, 0);💡 Best Practices
Do
- Use
save()/restore()around per-object transforms - Translate to the anchor point before rotating/scaling
- Keep transform order intentional (test it)
- Use
setTransform()to reset in animation loops if needed - Remember strokes and text are transformed too
Don’t
- Forget transforms persist and affect later drawings
- Call transform functions repeatedly without resetting (it accumulates)
- Assume order doesn’t matter (it does)
- Mix transforms across functions without scoping (hard to debug)
- Use huge scales on raster images without expecting blur
❓ Frequently Asked Questions
setTransform(1,0,0,1,0,0), resetTransform() (if available), or save()/restore().transform() multiplies the current matrix. setTransform() replaces it.Next: Canvas Translate
Learn how translation moves the origin and how to build reusable drawing functions.
4 people found this page helpful
