Using Trace Path

One way is through a nifty plugin (that comes with AE) called Create Nulls From Paths. Located in the Menu bar -> Window -> Create Nulls From Paths. There are currently 3 features available. The first one, as its name suggests, is to create a Null point at each anchor point of your chosen path. The path points are then parented to their respective Null's position. The second feature allows you to choose the inverse: where the Null's follow the path points. Finally, there is an option called Trace Path that is what we are interested in.

https://gfxhacks.com/content/images/2020/01/Screen-Recording-2020-01-26-at-01.09.17_edited.2020-01-26-01_38_33.gif

To work, you simply select your path, then choose Trace Path. This will create a Null that has its position constrained to the path you chose. It features a handy slider named Progress that you can access in the effects panel of the Null layer. Progress controls the flow of the Null along your path where 0% is the beginning, and 100% is the end of your path. Pretty straightforward! You also have a Loop checkbox option that allows the progress animation to loop the set keyframes. This works by toggling a loopOut('cycle') expression. You can see this if you toggle the expression panel of the progress control in the timeline.

//Expression applied to Null's "Progress" Slider
if(thisProperty.propertyGroup(1)("Pseudo/ADBE Trace Path-0002") == true && thisProperty.numKeys > 1){
thisProperty.loopOut("cycle");
} else {
value
}

All this expression is doing is verifying whether the Loop checkbox is checked == true **and that there are at least 2 keyframes set in the timeline numKeys > 1. If both are true then the loop is activated.

The remaining two properties that are controlled by expressions are position and rotation.

//Null Position Expression
var pathLayer = thisComp.layer("Path");
var progress = thisLayer.effect("Pseudo/ADBE Trace Path")("Pseudo/ADBE Trace Path-0001")/100;
var pathToTrace = pathLayer("ADBE Root Vectors Group")(1)("ADBE Vector Shape");
pathLayer.toComp(pathToTrace.pointOnPath(progress));

The position of the Null, relative to the path, is calculated using the pointOnPath() method; that returns the position of a point on the path based on a range of 0 to 1, where 0 is the position of the curve point at the beginning of the path, and 1 is the position of the curve point at the end of the path. To track progress of the flowing object, a percent scale is used for convenience, so the value passed as an argument to the pointOnPath() method must then be divided by 100 - to conform to the accepted range of 0 to 1.

//Null Rotation Expression
var pathToTrace = thisComp.layer("Path")("ADBE Root Vectors Group")(1)("ADBE Vector Shape");
var progress = thisLayer.effect("Pseudo/ADBE Trace Path")("Pseudo/ADBE Trace Path-0001")/100;
var pathTan = pathToTrace.tangentOnPath(progress);
radiansToDegrees(Math.atan2(pathTan[1],pathTan[0]));

The rotation property of the Null, at the specified progress time, is calculated by finding the inverse tangent (arctangent) of the path point using Math.atan2(), and then converting the result to degrees using the radiansToDegrees() function. In the next section we'll build a custom example to better understand how the math works and have a more customizable setup.

Animated Arrows

In a similar way to the Trace Path, we can setup objects to flow along the path as the path draws itself. Let's build an example with animated arrows. We'll be using a set of expressions that give us direct control over path points.

https://gfxhacks.com/content/images/2020/01/Animated-Arrows-2.2020-01-28-00_16_31.gif

What we'll be creating...

Setup

  1. Create a new comp at whatever size you prefer.
  2. In the new comp create a Layer > New > Shape Layer. Make sure its position is set to 0,0. Rename this layer to: "Path".
  3. Draw a path with the pen tool ( g key) while having the new Shape Layer selected. Once you are done, a group will be created in your shape layer contents that contains your path, a fill, stroke, and a transform. To simplify our example, drag your path and stroke out of the group and rename them to "Path", ****and "Stroke" respectively. Set your stroke width to a reasonable size for better visibility.
  4. Next add a Trim Path to your shape layer.