Some After Effects Tips

Lately I’ve been spending some time using After Effects to create motion graphics templates.  Today, I’ve got a few tips that might come in handy for others.

Over on Adobe Stock, they license .mogrt files, which are MOtion GRaphics Templates.   You can see my portfolio here: https://stock.adobe.com/contributor/207442241/seanlockephotography .  Due to backend issues, this is a separate account from my account that holds all of my photos and videos on the site.  This is just for .mogrt files.

The idea of the .mogrt is that an editor in Premiere can just import the file into their project, and then have just some easy sliders and text lines to modify, and they get a cool motion graphic result without all the work “behind the scenes”.

So, in putting these things together, I’ve discovered or come up with a few ideas that might help you along in your work, or that might answer a google search question (which I’ve used extensively!).  These notes all revolve around expressions, which is how you make a flexible template.  Expressions are written in javascript and will modify a value based on things in the expression.  Like if you want something to move in X as time passes, you can write “[time, 0]” as a simple expression for position.  That says the X value is whatever the time is, and Y is 0.

First off, the “intelligent text object”.  Most of these templates revolve around text in some way, whether it’s a title card, a lower third, or whatever.  And these templates tend to have a lot of effects and other things that happen based on that text.  Like a lens flare that travels across the text, or other things moving out of the way if the text is scaled up.  Now, there’s a really neat function that you can use on any layer in After Effects that will give you data about that layer.  It’s called “sourceRectAtTime”.  Basically, it will give you the top (y), left (x), height and width of any layer.  Which is really useful stuff.  So you use it all the time.

But there’s some tricks to it.  One is that if you use it on a text layer, the text lives in it’s own co-ordinate system, not the co-ordinate system of the composite you’re working on.  So it might tell you the left/top of your text object is 0,0, when it’s really sitting in the middle of the screen and you want the screen co-ordinates.  So you can use the function “toComp” to translate those co-ordinates, which is fine, but when you’re doing this repeatedly on every project, it gets tiresome and you can make mistakes.

Another issue with text is that text doesn’t scale from the center of the area the text takes up, but from the baseline of the text.  Now, if you’re doing a one off project, you can use the pan behind tool to re-center the anchor point (where the text scales from), but in these templates, things are changing all the time, so I needed a way to keep the anchor point centered, no matter what.

The solution is the “intelligent text object”.  Basically, in a nod to object oriented programming, I created a text object that I can import whenever I need it, that knows everything interesting about itself and keeps its center in the right place, and some other things.  So I don’t waste time messing with “sourceRectAtTime” in other expressions all day long.

These added effects “variables” hold expressions like (for “myTop”):

preTop = thisLayer.sourceRectAtTime().top;
preLeft = thisLayer.sourceRectAtTime().left;
thisLayer.toComp([preLeft, preTop])[1];

Or for “myHeight”:

if ( text.sourceText == “”) 0
else thisLayer.sourceRectAtTime().height * transform.scale[0] *.01; // takes into account any scaling on the layer because “height” lives in the text co-ordinates

Now, if I need to know how tall that text is, in screen space, I just call upon that value to find out.  Like if I have a box that resizes to fit some text inside of it, I can easily grab the text dimensions and use those to set the size of the box.  (Note, this is not the whole resize expression )

I mentioned keeping the anchor point centered in the text.  There’s an expression to do just that on the anchor point.  This doesn’t use those custom values above, because those are in screen space.  It uses “sourceRectAtTime” because the anchor point needs to be moved in the local co-ordinates of the text.

myX = sourceRectAtTime(time,false).width/2 + thisLayer.sourceRectAtTime(time,false).left;
myY = sourceRectAtTime(time,false).height/2 + thisLayer.sourceRectAtTime(time,false).top;
[myX,myY]

Another bit of magic is an expression that will keep text a certain pixel size on screen.  For example, if I have some shapes a line of text needs to stay within, I’ll use this expression.  It goes on the scale attribute, and if the text is wider than a certain number, the text object scales down inversely to stay within that range.  I used in on this template:

So, the user can type a longer bit of text for those lines, and the text will scale down to keep it between the snowflakes.   If I don’t need to worry about scaling and want to leave that up to the user, I just delete the expression and attach scale to a slider the user can use.

// super cool expression for scaling down text to keep it a certain size width
myWidth = sourceRectAtTime(time, false).width;
maxWidth = effect(“maxTextWidth”)(“Slider”);
myScale = maxWidth / myWidth*100;
if (myScale >= 100) myScale = 100;
// use this next line to limit scale downwards
if (myScale<=75) myScale= 75;
[myScale,myScale];

So, that’s the idea of the “intelligent text object”.  Here’s an example of how I used those pre-figured values.  I needed to know the perimeter of a shape (box) that surrounds my text.  The perimeter isn’t just length x width x 2, because I allow the user to set the roundness of the corners of the box.  So, I wrote this expression that takes into account that variable.  I added a slider effect to the box called “myPerimeter” and figured it out this way:

myWidth = content(“Rectangle 1”).content(“Rectangle Path 1”).size[0] – (content(“Rectangle 1”).content(“Rectangle Path 1”).roundness*2);
myHeight = content(“Rectangle 1”).content(“Rectangle Path 1”).size[1] – (content(“Rectangle 1”).content(“Rectangle Path 1”).roundness*2);
myHeight *2 + myWidth *2 + 2*Math.PI *content(“Rectangle 1”).content(“Rectangle Path 1”).roundness;

It takes the X value of the size (essentially, the width) and subtracts the roundness value x 2.  Roundness is a value that tells the radius of the corner.  So a roundness value of 10 means we need to subtract 10 pixels from each end of the width.  Instead, at those ends, we need to know the circumference of the circle that represents all of the 4 corners.  The formula for circumference is 2 x PI x R.  So, that just gets added on to the end.  If there is no roundess, it works.  If there is, it works.  Cool.

There’s some .mogrt tips.  I’ll try to write about some more another day if I get the chance.

Thanks!

 

Comments are closed.

This image is protected by copyright law. Please contact me for licensing information. Thanks!