Hacking expressions

Posted on 22. May, 2008 by in Blog

You all know that I’m a expression junkie. You’ve seen my tutorial and my approach to animating things. I hate keyframes, I love expressions. Even though sometimes I find using expressions very frustrating. Theres no way to declare global variables, create your own functions, or extend the build-in functionality. But there actually is a nice way to deal with that that you might not be aware of.

This is going to be very interesting if you have any programming experience. Any programming language will do: C++, PHP, Ruby, Visual Basic, Java, or even ActionScript. AE Expressions are based on JavaScript, so they are not only object oriented. You can also use any JavaScritp syntax and build-in functions that are not listed anywhere in AE itself. Unfortunately some things will not work as expected, and sometimes you might even get an error message, when everything is ok. When that happens simply turn off the expression and turn it back on again, or select all, cut it out, press Enter, and then paste it again making sure that you don’t have any white spaces in the beginning or end of the expression. That helps sometimes.

For example:

var currentTime = new Date();

In Javascript this creates a new variable that holds the Date object, that if no attributes are used in the constructor points to the current local time represented in milliseconds. If you’d try that in expressions you’d get an error. AE will force you to pass some attributes to the constructor. But that doesn’t mean we’ll not gonna have any fun.

Create a new text layer, and in the text source property try this code:

this;

Aaaahhh…. Ok. We’re getting somewhere. But what is this (object Layer) thing? Lets find out. Next piece of code will enumerate all properties of the object Layer.

Replace the above code with this one:

myPropList = []; //declare new array
currentFrame = timeToFrames(time, 1 / thisComp.frameDuration, false);
targetObj = this;
for (var itm in targetObj) {
myPropList.push(itm);
}
myPropList[currentFrame];

Now use PageUp and PageDown to go through frames of your composition. On each frame you should see different properties of the layer. It’s interesting, but lets move to something more useful.

Lets say you’re doing a text based animation. For example a counter that should go from 0000 to 9999. Notice that it’s 0000 to 9999, not 0 to 9999. So to do that you’d have to write a bunch of code to add additional 0 at the beginning, right? But what if you could design a function to do that for you? Since you can have functions in Javascript, it’s worth to try it in expressions as well. So lets try it.

function formatNumber (val, basestr) {
return basestr.substr (0, (basestr.length - val.toString().length)) +  val.toString();
}

formatNumber(132, "0000");

This little piece of code takes two parameters. First one is the numeric value, and the second one is the output format for that value. So for example, if you have a number 132, and an output format 0000 as the result you’ll get 0132. Also, if your number is 132 and output format is ABCDEF the result will be ABC132. As you see this is a pretty useful function. The only downside is that each time you want to use it you have to write it from scratch. Not very optimal solution.

So how do you make your own functions reusable in expressions?

As said before – expressions are Javascript based pieces of code, and that means you can basically use any Javascript syntax. There fore why not try using #include statement? Let’s try it out. Copy the formatNumber function to your clipboard and save it as a file on your hard drive. Let’s assume that the path to the file is "c:myUtils.java". Having that file setup everything left to do is to import it like that:

#include 'file:///c:myUtils.java'
formatNumber(132, "0000");

If you’re on Windows you might want to save your file in the Support Files directory that you can find inside of After Effects installation directory. The default path for that is C:Program FilesAdobeAdobe After Effects CS3Support Files. I’m guessing that on a Mac this should be similar, but you will probably have to option-click on your AE directory and choose “Show package content”. After that you can navigate to /Applications/Adobe After Effects CS3/Adobe After Effects CS3.ap/Contents/Resources/ and put the file there. Than you’ll be able to simply use #import 'file:///myUtils.java' instead of providing the whole path to your file.

You can also use this technique to drive variable values from an external file. For example:

myText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam ultricies sapien et justo. Vestibulum et erat id ante imperdiet sollicitudin. Ut sed ligula ac mauris tempus egestas. Donec vel risus."

Please keep in mind that this is a hack and it’s not officially supported, although I think it will work with any expression-enabled AE version. Try to keep your code libraries as small as possible. Group your functions to separate files to help organize your code. Remember that each time you import a file all it’s content is being processed my AE expression engine and this may slow things down quite a bit.

I hope you found this article useful. Leave a comment and let me know what you think.
Thanks for reading.

Tags: , ,

21 Responses to “Hacking expressions”

  1. UmairVFX

    22. May, 2008

    hahahahahahha ;)

    Really really intersting amazing awesome buddy;;;

    maltaannon = theBest()*1000;

    [maltaannon,maltaannon];

  2. Maltaannon

    22. May, 2008

    Thant’s a nice expression, but I think it should rather be:
    maltaannon = theBest()*(time*1000);
    [maltaannon,maltaannon];

  3. Calvin

    24. May, 2008

    ahh , sorry guys but i think it should rather be :

    maltaannon = the best()*exp(time*100);
    [maltaannon,maltaannon]

    thanks for this

    btw,don’t try my expression,it’ll take between 3 to 4 hours to render one frame

  4. Maltaannon

    24. May, 2008

    again… theres a small error:
    maltaannon = theBest()*exp(time*100);
    [maltaannon,maltaannon]

    • Thomas

      09. Aug, 2010

      Great article, Maltaannon.

      BTW:

      Math.exp(..

      :P

  5. Ricky

    25. May, 2008

    Who’s the expression junkie?!? :D
    Amazing, simply no words ;)

  6. UmairVFX

    25. May, 2008

    haha guys i think it should be like this;

    maltaannnon = theBest();
    jezy = wiggle(5,500)/5;

    [maltaannon,jezy]

    hope this brand new expression will work();

    its Free guys just use it and feel free to ask be about it… ;)

    hahah

    Check this out and post comments;

    http://www.youtube.com/user/umairvfx

  7. Mark

    26. May, 2008

    hmm interesting, but i cannot understand anything here, dont have the programming knowledge. Mark

  8. vianz

    26. May, 2008

    hmmh..what a brilliant, i don’t even know what that’s mean.

  9. Erilaz

    21. Jun, 2008

    Thanks man… I never knew you could use #includes inside the expressions. This will be very useful!

  10. Ecker00

    24. Jul, 2008

    Your a genius dude! i didn’t even know AFX did even use javaScript =O but i feel like i should know that for a long time ago. Anyway, thanks for sharing your knowledge!

    #include ‘/the.world’

  11. Clint

    15. Aug, 2008

    i am having issues getting this to work on my Mac using CS3. I have tried putting the file in Resources folder as suggested and in a few other simple to link-to locations, but still have had no luck. Any ideas?

  12. Maltaannon

    15. Aug, 2008

    Try changing the file path to this format: file:///yourfilepath.ext

  13. krajstof

    04. Oct, 2008

    This might come in handy :)

  14. bryab

    27. Oct, 2008

    is it just me, or does this not work in AE CS4?

  15. Elliot Mebane

    24. Nov, 2008

    Great tip. I’m using Win XP 64 bit with AE CS3. My findings vary from the notes in this post. I’ve been unable to target the same folder the AEP file is in with relative referencing. That’s my preference so my project can be more portable. Anyone have success with that?

    Here’s my findings. Hopefully this helps someone else use this great tip about the #include directive:

    I used the following format, without any file:/// prefix, and I was able to target the Support Files folder (the sample with file:/// targets the root of my C drive):
    #include “simpleNumber35.jsxinc”;

    Any filename/extension works, but I followed the jsxinc format I read about in the PDF guide referenced below.

    Example that targets the root of my C drive: #include “file:///simpleNumber50.jsxinc”;

    Example that targets a sub directory (note: no c:\\ needed. None of my trials worked when I included c:\\):
    #include “file:///Documents and Settings\\Administrator\\My Documents\\simpleNumber90.jsxinc”;

    Links to another thread that cites #include (again, my results are different than the results that are cited here):
    http://aenhancers.com/viewtopic.php?p=3420&sid=c63f9a5278cac83b47390f798063c92e#p3420

  16. Maltaannon

    24. Nov, 2008

    That’s true. You can’t reference relative folder – at least I haven’t found any way of doing that. The file:/// is just good to use if you’re using the same project file and file structure on two systems like MacOS and Win, but it’s not required.

  17. ElenaLisvato

    04. Aug, 2009

    That’s Too nice, when it comes in india hope it can make a Rocking place for youngster.. hope that come true.

  18. Heexakyreathe

    09. Apr, 2010

    Nice web. Maybe you should try to monetize it with
    http://prosperent.com/ref/214626
    New affiliate network, time to say goobye to adsense!

  19. terry

    24. Jan, 2013

    hello

  20. Thomas

    09. Aug, 2010

    ..Sniff..Sniff.. Spam?