Creating 3D Rotations with the Canvas Transformation Property

In our last post we discussed how you can use the canvas rotation property to create interesting effects in your Javascript games; today we will be extending this a bit to create realistic rotations in 3D. Examples of this effect include the rotating coins in EntombedBrimstoneRocket Racers 2 and Volcano Frenzy, the rotating heiroglyph at the end of each level in Entombed, and the tumbling tracks that fall into the cavern in Volcano Frenzy. In addition to making objects rotate, it can be used to give 3D depth to 2D objects such as the flames in Brimstone (we will talk more about this in a later post).

Before we begin, we should make it clear that this method is not a full substitute for 3D graphics; rather, it is a neat little hack which can trick your 2D context into rendering 3D effects.

Rotation Matrices

Once you start mucking about with three-dimensional rotations, you need to start using rotation matrices or your graphics will start to pick up some unphysical traits (this is technically called torqueless precession, and it looks super weird).

There are three basic rotation matrices, found here, and each one represents rotation in a different direction. Rather than keeping track of an angle for our object, we will be keeping track of an entire rotation matrix. Initially that matrix will be set to the 3x3 identity, but every time it rotates we will multiply it by the appropriate matrix. For example: if our object rotates by angles η, θ, and φ in the xy and z directions respectively, then its rotation matrix should be multiplied by the corresponding elemental rotation matrix for each of these directions: R = Z(φ)Y(θ)X(η)R. Note that the elemental rotation matrices should always be multiplied in the same order every time, and they should always be multiplied to the left of the rotation matrix R.

The beauty of this is that once we have a rotation matrix R, we can input it directly into the canvas using the transform property as follows:

context.transform(R[0][0],R[1][0],R[0][1],R[1][1],R[0][2],R[1][2]);

Just as with rotations, we first need to transform to an axis of rotation.

Causing an Image to Rotate out of the Page

The effect we are going to create here is the one depicted with the rotating coin below:

To create this effect, we did the following simple steps:

  • We gave the coin a rotation matrix initialized to the identity.
  • With each step we multiplied the rotation matrix by three elemental rotations.
  • To render each step, we translated to the center of the canvas, passed the rotation matrix to the context.transform property, and transformed back.

Note that aside from the transformation step, everything else is quite similar to the rotations we did in our previous post.

How did we know what rotations to pass the coin in order to make it spin in that exact fashion? That required a small amount of vector math.

If the coin were pointing straight out of the page, its angular velocity would point completely in the negative y direction. If we rotate this vector by θ in the x and φ in the y, such that it points slightly out of the page but we can still view its side, the components of its angular velocity will be

ωx = -ω*sin(θ)*sin(φ)
ωy = -ω*cos(θ)
ωz = -ω*sin(θ)*cos(φ)

With each step we then rotate the coin by the angles (ωx,ωy,ωz). The angular speed ω determines how fast the coin rotates (we used 5 degrees per 30 milliseconds), and the angles θ and φ determine where its axis points (we used -50 and -20 degrees, respectively).

Games Mentioned in this Post:

1 thought on “Creating 3D Rotations with the Canvas Transformation Property”

Leave a Reply

Your email address will not be published. Required fields are marked *