CONTENTS OTHER MATERIAL |
Ranges of Values While the pick whip attempts to fix errors from mismatched dimensions, it does not attempt to make your expression’s results particularly meaningful or useful. That’s up to you. In particular, you may need to adjust the range of values from an ‘incoming’ parameter in order to make them better fit your target parameter. For instance, when we earlier used rotation to drive opacity, you may have noticed that opacity maxed out after only 100 degrees of rotation. But what if we’d wanted the layer to become fully opaque only after a complete revolution (360 degrees)? We’d need to adjust the range of incoming values to match our needs. An easy way to scale a range of values is to first divide by the maximum incoming value, and then multiply by your desired maximum outgoing value. For instance, in the rotation and opacity example mentioned above, we want to scale the rotation range of 0—360 to a range of 0—100 for opacity. So we’d first divide by 360, then multiply by one hundred: rotation / 360 * 100 Opacity will now use all 360 degrees of rotation: How does this work? Simple: by dividing by 360, we effectively compress the incoming rotation values to a range of zero to one. When we then multiply by one hundred, the maximum value for opacity, we expand our values back out to a range of zero to one hundred. We can do a lot with this simple technique. For instance, we can create a wheel, where changes in a layer's position will drive its rotation. We simply need to scale the position values to produce the correct rotation: 360 degrees every time the wheel travels forward one circumference. Basically, rotation=distance/circumference*360: So how do we know that this is the right formula? How did we arrive at the final expression? It may seem like a pretty big leap from the opacity example above, but it really isn't. To start out, we know that our expression is going to link changes in position to changes in rotation — that's pretty much what a wheel does. But should position drive rotation, or should rotation drive position? Either one will work. I decided to have position drive rotation simply because it's more fun — you can drag the layer around the comp window, and watch it rotate as though it actually were rolling. So we want to add an expression to the layer's rotation, and know that expression will somehow use values from the layer's position parameter. This rough beginning gives us something like: rotation=position*? I've decided to make things easier by saying that our wheel will only roll horizontally. This lets us just use the X component of the layer's position (aka 'position[0]') to calculate how far the layer has moved: it will start at zero at the left edge of the comp, and increase as the layer travels to the right. (Remember that AE's coordinate system starts the upper left corner of each comp.) So now we have: rotation=position[0]*? We know from experience that when a wheel travels a length equal to its circumference, it rotates one full revolution. Otherwise, it would slip against the ground. So, using the language we used above, we'll say that the wheel's circumference is our 'maximum' incoming value. A full revolution, or 360 degrees, is the corresponding 'maximum' output value. So we need to divide by the circumference and multiply by 360: rotation=position[0]/circumference*360 Of course, one circumference and one revolution aren't really 'maximum' values — the wheel could travel and rotate further. But our expression doesn't care if these values are really maximums or not. It just uses them to build an exchange ratio to convert values from one range to another: 360 degrees of revolution for every circumference of movement forwards. So now we need to define 'circumference'. A circle's circumference is equal to its diameter times PI: We can use our layer's width as its diameter (so long as it is in fact as wide as its layer). Javascript includes a built in, highly accurate value for PI, which we can access by writing 'Math.PI' (of course, we also could just write '3.14' and we'd be OK): circumference=width*Math.PI; Finally, we can delete 'rotation=' from our basic formula, because that assignment is already implied by the fact that our expression is applied to the rotation parameter. When we put these pieces together, we get this final expression for our wheel, applied to its rotation parameter: distance=position[0]; I'll leave it to you to figure out how to account for changes to the wheel layer's scale. In the meantime, try applying this in situations where layer's don't typically roll around, e.g. type: You may be wondering why I've spent so much time on this. After all, you could easily keyframe rotation and position together, and create a realistic looking wheel. Well, that may be true for a wheel moving forward at a constant speed, but you'd find it very difficult to make the wheel slow down or speed up without looking like it was slipping against the ground. Changes in acceleration like this are very tough to do manually, but are handled perfectly by an expression. If you want more information about this example, I describe this same project in more detail here. |

Entire contents © 2001 JJ Gifford.