As an exercise to practice our expression coding skills, we would like to create a color wheel using a single shape layer and expressions. The wheel should be made with colored arcs of varying hue, saturation and lightness. We want 4 levels of tint and 12 arcs per level (subdivisions). The following figure shows the different parts of the wheel and the notation we’ll use in the expressions:

Constructing The Base Arc

We want to create an initial arc, add expressions to it, and then duplicate that arc to construct the entire wheel. The setup consists of a shape group containing a trimmed stroked ellipse:

Since the wheel is made of concentric circles, the size of each circle depends on the level. We apply the following expression to the ellipse size:

The expression is the same for the end property, except the last line:

...
(arcIdx + 1) * (100 / subdivs);

The stroke width is set to 10% of the comp height:

0.1 * thisComp.height;

And finally we apply the following expression to the stroke color:

subdivs = 12;
numLevels = 4;
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;
levelIdx = Math.floor(idx / subdivs);
arcIdx = idx % subdivs;
h = arcIdx / subdivs; // hue
s = 1 - levelIdx / numLevels; // saturation (from high to low)
l = linear(levelIdx, 0, numLevels-1, 0.5, 0.3); // lightness (remap range)
a = 1; // alpha (doesn't affect the result here)
hslToRgb([h,s,l,a]);

This should produce something like this:

Duplicating The Base Arc

Quite a lot of code for drawing a simple arc, but now comes the fun part. We simply press Ctrl+D (Cmd+D on Mac) to duplicate the base arc until the wheel is complete:

When the number of arcs reaches 48 (i.e., 4 x 12), the wheel is complete:ession to the ellipse size:

Reveal Animation

As a bonus we would like to animate the construction of the wheel. To this end, we add a second Trim Paths effector to the base arc (don’t forget to remove every other arc):

We add the following trim end expression to sequentially reveal the arcs with a short delay:

The expression is the same for the out tangent except the vector points in the opposite direction:

Conclusion

Through this little exercise we have seen how we can manipulate shapes and colors using simple expressions. Hope you find it useful!

You can also check ConnectLayers PRO, a tool that create lines that are dynamically linked to the layers using powerful path expressions. No keyframes at all!

To some extent, Newton 3 reminds me of an open-world video game where the player’s choices can alter what will happen at any given time. While there’s usually a direct start and endpoint for many effects within After Effects, with Newton 3, you can obtain a new result, and thus a new animation, on an infinite scale. I don’t try to be stubborn with my reviews, but I most definitely won’t gloss over the downfalls of a product.

But with Newton 3? I’m just not seeing it. To import several shapes, apply real-world physic simulations with a click of a button, and then render them within a few seconds is a game changer for me. I can’t picture when I wouldn’t use this plugin for most future animations. I’ve had Newton bookmarked for so long that the original bookmark refers to the older version of the plugin. I can only wonder how great my previous videos could have been if I had purchased the plugin sooner.

We want to draw the cube vertices with filled ellipses, and connect them with thin stroked lines. We would like to create a single point, apply an expression to its position, and then duplicate that point to create the other points. Once all points are created, we will draw the edges.

Math Utils

Manipulating 3D vectors (rotation, projection) is easier with matrices. Since there aren’t any built-in matrix utilities in the expression language, we must create our own. To avoid having a too long expression, we decide to put our matrix code in an external js file (e.g., “matrix.js”). This file can be imported into our our expression at runtime.

We only need basic stuff here: multiply a matrix and a vector, multiply two matrices… Here is our matrix library:

function vecToMatrix(v)
{
var m = [];
for (var i = 0; i < 3; i++)
{
m[i] = [];
}
m[0][0] = v[0];
m[1][0] = v[1];
m[2][0] = v[2];
return m;
}
function matrixToVec(m)
{
return [m[0][0], m[1][0], m.length > 2 ? m[2][0] : 0];
}
function matMatMul(a, b)
{
var colsA = a[0].length;
var rowsA = a.length;
var colsB = b[0].length;
var rowsB = b.length;
var result = [];
for (var j = 0; j < rowsA; j++)
{
result[j] = [];
for (var i = 0; i < colsB; i++)
{
var sum = 0;
for (var n = 0; n < colsA; n++)
{
sum += a[j][n] * b[n][i];
}
result[j][i] = sum;
}
}
return result;
}
function matVecMul(a, v)
{
var m = vecToMatrix(v);
var r = matMatMul(a, m);
return matrixToVec(r);
}

Creating The Vertices

First we need to import the matrix lib (“matrix.js”) into our ellipse position expression. This is done with the following line of code:

$.evalFile("F:/Documents/JSX/matrix.js");

Then we set some design variables and retrieve the index of the cube vertex:

r = 200; // cube size
distance = 2; // affects perspective
rotSpeed = 0.06; // in radians per frame
idx = parseInt(thisProperty.propertyGroup(3).name.split(" ")[1]) - 1;

We need to determine the location of each vertex from its index. To do that we can use the following formula (taken from math.stackexchange):

p = []; // 3D vertex position at start
bs = [];
for (i = 0; i < 3; i++)
{
bs[i] = (idx >> i) & 1;
p[i] = 0.5 * Math.pow(-1, bs[i]);
}

Note that the above formula will position the vertices in the following order (front face: 1-2-4-3, back face: 5-6-8-7):

Now that we have found the 3D starting position of the vertices, we can dive into the main part of this exercise. We basically loop through every previous frame, setup rotation matrices based on the current angle, apply 3 successive rotations (around Y, X, and Z axis), and finally project the 3D vertex to find its 2D position inside the shape layer. Here is the beast:

angle = 0;
for (t = 0; t <= time; t += thisComp.frameDuration)
{
// rotation matrices (https://en.wikipedia.org/wiki/Rotation_matrix#Basic_rotations)
rxMatrix = [[1,0,0], [0,Math.cos(angle),-Math.sin(angle)], [0,Math.sin(angle),Math.cos(angle)]];
ryMatrix = [[Math.cos(angle),0,-Math.sin(angle)], [0,1,0], [Math.sin(angle),0,Math.cos(angle)]];
rzMatrix = [[Math.cos(angle),-Math.sin(angle),0], [Math.sin(angle),Math.cos(angle),0], [0,0,1]];
// do rotations (the order matters, here we chose it arbitrarily)
p3d = matVecMul(ryMatrix, p);
p3d = matVecMul(rxMatrix, p3d);
p3d = matVecMul(rzMatrix, p3d);
// increase rotation angle
angle += rotSpeed;
}
// handle perspective
z = 1 / (distance - p3d[2]);
// project 3D point
projectionMatrix = [[z, 0, 0], [0, z, 0]];
p2d = matVecMul(projectionMatrix, p3d);
// scale result
mul(p2d, r);

To create the cube vertices we just need to duplicate the first Ellipse group 7 times.

We obtain the following animation:

Great, our calculations seem correct. Now we need to connect those dots to finish the cube.

Creating The Edges

Since we cannot connect all vertices with a single path, we need to create multiple connecting lines. We want these lines to be constructed from the same unique expression, and control the connected vertices by specifying their indices in the shape’s group name.

Here is the first connecting path which connects the first four vertices (i.e., the front face):

We apply the following expression to the path property of the connection:

indices = thisProperty.propertyGroup(3).name.split("Connection ")[1].split(" ");
pts = [];
for (i = 0; i < indices.length; i++)
{
idx = indices[i];
pt = content("Ellipse " + idx).content("Ellipse Path 1").position;
pts.push(pt);
}
createPath(pts, [], [], false);

For creating every other connection we duplicate the first connection and rename it with the appropriate indices list for that connection. The final timeline looks like this:

It’s time to press the 0 key on the numpad to preview the final animation.

Conclusion

In this exercise we have shown how to project a 3D object onto a 2D plane using expressions. We have created our own matrix library to facilitate 3D calculations, and imported it into our expression. We used it to setup and manipulate rotation and projection matrices. Hope you find it useful!

You can also check ConnectLayers PRO, a tool that create lines that are dynamically linked to the layers using powerful path expressions. No keyframes at all!

We first create a simple path animation using a shape layer. This will serve as a base path for our exercise. The position of the shape layer has been set to 0,0 in order to simplify our expressions.

The timeline looks like this:

Recreating the path

We would like to recreate the initial path using a path expression applied to a new shape layer. This is done with the following expression:

The initial path was using Fill only, so we use Stroke only for the replicated path. We also set the layer’s position to 0,0. The timeline looks like this:

Traveling Along The Path

We would like to create a dot that travels along the path. We want the animation to span the entire comp duration: the dot should start its journey at t=0, and it should reach the end of the path at the end of the comp.

The dot is represented as a small filled and stroked ellipse:

We use the following ellipse position expression to make the dot traveling along the path:

Through this little exercise we have seen all path properties available in expression. We were able to create a path by specifying its vertices and tangents, and were able to visualize tangent and normal vectors of a point traveling along the path. Hope you find it useful!

You can also check ConnectLayers PRO, a tool that create lines that are dynamically linked to the layers using powerful path expressions. No keyframes at all!

We first create a simple horizontal path using a shape layer. We make sure to set the layer’s position to 0,0 so the coordinates of the vertices will correspond to points in comp space (this will simplify a little bit our expression).

Then we add a Trim effector and create two keyframes to animate the end of the path from 0% to 100%. For the second key, we apply an Easy Ease In and multiply the influence of the incoming velocity by two (i.e., from 33.33% to 66.66%).

Now we create the layer we would like to attach to the end of the path. We make sure its position corresponds to the center of the comp (the default value) and its anchor point is located at the left hand side of the layer.

The timeline looks like this:

To attach the layer to the path, we need to find the location (in comp space) of the end point of the path. This is done with the following position expression:

Let’s see if we can add a small gap between the end of the path and the attached layer. Since our path is a straight horizontal line, we only need to shift the layer to the right along the x-axis. We add the following code to the previous expression:

...
gap = 15; // distance in px between the path and the layer
endPt + [gap,0];

Add Pepper

Now we would like to try with a more complex path, say an arbitrary Bezier path. Note that the end vertex has a non-zero tangent vector.

The code for the gap must be changed to take into account the direction pointed by the path (i.e., the tangent vector at the end of the path):

...
gap = 15; // distance in px between the path and the layer
tg = myPath.tangentOnPath(trimEnd);
endPt + gap * tg;

Add Cayenne Pepper

Now we would like to rotate the layer so it’s oriented along the path. To this end, we could use the corresponding built-in feature in AE:

Not that bad, but notice how the layer suddenly changes its orientation at the end of the animation. So let’s try to orient the layer using the following rotation expression (don’t forget to turn Auto-orient off before applying the expression):

For better control we could precompose our layer and make some design changes in the precomp. We don’t want the (precomp) layer to overlap the end of the path so we position the content of the precomp at the center of the precomp, and left-align the content since our path animation goes from left to right.

Conclusion

We have shown how to attach a layer to the end of a path using simple expressions. Hope you find it useful!

If not, you can use or tool Connect Layers Pro to add arrow heads to your path!

Joyce N. Ho is a Hong Kong born, Australian designer, based in New York City.

In 2019 she designed an animated poster for San Francisco Design Week using Newton

Here’s the final video:

“I created a motion poster for @sfdesignweek this year, on the theme of “CommUNITY”. My design is inspired from the idea that we come together to comfort, collaborate and communicate with each other – to be part of something bigger than ourselves.“

Une publication partagée par Joyce N. Ho (@joyce.n.ho) le

And she also created the very interesting Newton mini tutorial to reveal the technical process behind the animated poster!

As an example, she create a null object that will control the gravity with random values inside Newton!
She also used the magnet system and different simulations assemble in a final composition.

You may know that you can use Adobe Illustrator files with Newton for Adobe After Effects. You can do this by using different techniques like converting them into shape layers.

It’s important to know that the more your objects are complex, the slower your simulation will be.
Also, you won’t get better results if you use complex objects in your simulation. And by complex, we mean plenty of path vertices and detailed Bezier curves.

So, what are the best practices?

Use a mask

You can apply a mask to your Illustrator layer so Newton can interpret its outline correctly.
You can also use the auto-trace function of Adobe After Effects.
If you copy/paste the path from Illustrator, you should use before the “Simplify” and “Cleanup” function in Illustrator to have the most optimized shape.

Note that here, what’s inside the robot has been removed since we don’t need it for the simulation. The mask only cover the outline of the artwork.

Converting your Ai files to shape layers

You can convert your Ai file to shape layers.
But be sure to ONLY send to Newton what’s needed. You can simply hide the path or the groups that you don’t want to use in Newton and unhide them after the simulation is complete.
In this example, mouth and eyes are not needed for the simulation and will be unhidden after the simulation is complete.

Also, always try to simplify the transformation applied to your shapes. In most cases it is recommended to have the inner transform of a shape (transform properties of groups for example) set to the default values and use layer’s transform instead.

Watch for self-intersecting shapes!

Newton prevents to load shapes and masks that have self-intersecting path or orphan vertex. It will warn you if one of the paths cannot be correctly interpreted. You’ll then have to manually modify it.
Be careful when working with paths created using tools like the cutter tool in Ai!

Creating proxy version
of your objects

Best pratice to use complex Ai vectors is to replace them by a less complex version of them and simply parent them to the original ones.
Just like in this breakdown.

Need more tips and tutorials?
Check our Learn page!

How to Create 3D Shapes with Newton 3

Although Newton 3 is a 2D physics simulator and only accepts 2D shapes and text, there’s a small workaround to incorporate 3D shapes.

Color Wheel

Manipulating shapes and colors using expressions

3D Projection

Creating and projecting a 3D cube onto a shape layer using expressions

So, you have upgraded to the last version of macOS 10.5 Catalina. But suddenly when you launch After Effects you get that message that tells you that you cannot run Newton.

Now, the bad news: support has been dropped for Newton2.
The good news, you can still use it with macOS 10.5 Catalina, here’s how!

→Or you can go to your security preferences into macOS to allow Newton2 to run it (more info here):

– You have to launch Adobe After Effects and macOS will say that Newton2 is not signed.
-Click cancel
-Go to your security preference.
-MacOS will ask you if you want to run Newton2.
-Click Open Anyway

Fixed!

Note that if you have the same message with Newton3, you just need to download and update to the last version.