diff --git a/pixelgl/canvas.go b/pixelgl/canvas.go
index 723b544a1234b145f824401eb2ac3cdc1c455e7e..038bcc01c5dd85ae2e7759dba6d68ba94d86fbc2 100644
--- a/pixelgl/canvas.go
+++ b/pixelgl/canvas.go
@@ -123,7 +123,7 @@ func (c *Canvas) SetBounds(bounds pixel.Rect) {
 		c.sprite = pixel.NewSprite(nil, pixel.Rect{})
 	}
 	c.sprite.Set(c, c.Bounds())
-	c.sprite.SetMatrix(pixel.IM.Moved(c.Bounds().Center()))
+	//c.sprite.SetMatrix(pixel.IM.Moved(c.Bounds().Center()))
 }
 
 // Bounds returns the rectangular bounds of the Canvas.
@@ -245,12 +245,18 @@ func (c *Canvas) Pixels() []uint8 {
 	return pixels
 }
 
-// Draw draws a rectangle equal to Canvas's Bounds containing the Canvas's content to another
-// Target.
+// Draw draws the content of the Canvas onto another Target, transformed by the given Matrix, just
+// like if it was a Sprite containing the whole Canvas.
+func (c *Canvas) Draw(t pixel.Target, matrix pixel.Matrix) {
+	c.sprite.Draw(t, matrix)
+}
+
+// DrawColorMask draws the content of the Canvas onto another Target, transformed by the given
+// Matrix and multiplied by the given mask, just like if it was a Sprite containing the whole Canvas.
 //
-// Note, that the matrix and the color mask of this Canvas have no effect here.
-func (c *Canvas) Draw(t pixel.Target) {
-	c.sprite.Draw(t)
+// If the color mask is nil, a fully opaque white mask will be used causing no effect.
+func (c *Canvas) DrawColorMask(t pixel.Target, matrix pixel.Matrix, mask color.Color) {
+	c.sprite.DrawColorMask(t, matrix, mask)
 }
 
 type canvasTriangles struct {
diff --git a/sprite.go b/sprite.go
index 6ac9aebe1c1ba6fb2d1eeee9902ac9ffe6a80304..45989d691d38f7d851cabd8d97964af8c5cc3181 100644
--- a/sprite.go
+++ b/sprite.go
@@ -57,43 +57,35 @@ func (s *Sprite) Frame() Rect {
 	return s.frame
 }
 
-// SetMatrix sets a Matrix that this Sprite will be transformed by. This overrides any previously
-// set Matrix.
+// Draw draws the Sprite onto the provided Target. The Sprite will be transformed by the given Matrix.
 //
-// Note, that this has nothing to do with BasicTarget's SetMatrix method. This only affects this
-// Sprite and is usable with any Target.
-func (s *Sprite) SetMatrix(matrix Matrix) {
-	if s.matrix != matrix {
-		s.matrix = matrix
-		s.calcData()
-	}
+// This method is equivalent to calling DrawColorMask with nil color mask.
+func (s *Sprite) Draw(t Target, matrix Matrix) {
+	s.DrawColorMask(t, matrix, nil)
 }
 
-// Matrix returns the currently set Matrix.
-func (s *Sprite) Matrix() Matrix {
-	return s.matrix
-}
-
-// SetColorMask sets a color that this Sprite will be multiplied by. This overrides any previously
-// set color mask.
+// DrawColorMask draw the Sprite onto the provided Target. The Sprite will be transformed by the
+// given Matrix and all of it's color will be multiplied by the given mask.
 //
-// Note, that this has nothing to do with BasicTarget's SetColorMask method. This only affects this
-// Sprite and is usable with any Target.
-func (s *Sprite) SetColorMask(mask color.Color) {
-	rgba := ToRGBA(mask)
-	if s.mask != rgba {
+// If the mask is nil, a fully opaque white mask will be used, which causes no effect.
+func (s *Sprite) DrawColorMask(t Target, matrix Matrix, mask color.Color) {
+	dirty := false
+	if matrix != s.matrix {
+		s.matrix = matrix
+		dirty = true
+	}
+	if mask == nil {
+		mask = Alpha(1)
+	}
+	if mask != s.mask {
 		s.mask = ToRGBA(mask)
-		s.calcData()
+		dirty = true
 	}
-}
 
-// ColorMask returns the currently set color mask.
-func (s *Sprite) ColorMask() RGBA {
-	return s.mask
-}
+	if dirty {
+		s.calcData()
+	}
 
-// Draw draws the Sprite onto the provided Target.
-func (s *Sprite) Draw(t Target) {
 	s.d.Draw(t)
 }