曲線に沿って矢印が進み、カーブに合わせて向きも変わる。pointOnPath() と tangentOnPath() を使うと、描いたパスを移動ルートとして参照できます。
今回は、丸のパス移動から、地図風のルート案内、描かれる線の先端を矢印が追う作例へ進みます。ルートを描き直しても、位置のキーを作り直さず追従できるのが、この方法の便利なところです。
この記事で使用したAEプロジェクトを無料ダウンロードできます。ダウンロードは記事の最後から。
まずは完成形:丸が線に沿って移動する
アニメーションさせるのは、進行率を表す1本のスライダーです。手で位置のキーを並べる代わりに、パスの形と進行率から、現在位置を計算します。
pointOnPath()とtangentOnPath()の役割
| 書き方 | 何を取り出すか |
|---|---|
| path.pointOnPath(u) | パスの長さに対する割合uの位置座標 |
| path.tangentOnPath(u) | その位置でパスが進む方向を表す接線ベクトル |
| u=0〜1 | 0が始点、1が終点。50%なら0.5 |
| route.toComp(…) | ルートレイヤー内の座標をコンポジション座標へ変換 |
進行率は頂点の個数ではなく、パスの長さに対する割合です。4頂点だから各頂点が0・33・66・100%になる、という意味ではありません。開いたパスでは0が最初の頂点、1が最後の頂点です。閉じたパスでは0と1が同じ場所になります。
準備:ルート・進行率・丸の3レイヤーを作る
| 項目 | 今回の条件 |
|---|---|
| 環境 | After Effects 26.5×89/macOS/JavaScriptエクスプレッションエンジン |
| コンポジション | 1280×720/30fps/6秒/8bpc |
| ROUTE | シェイプレイヤー。Routeグループ内にPathという開いたベジェパス1本。塗りなし・線8px |
| CTRL | ヌルオブジェクト。Progressという名前のスライダー制御を追加 |
| DOT | 直径34pxの丸。中心とアンカーポイントを揃える |
| 共通条件 | 2D/親とリンクなし/位置の次元分割なし/追加プラグイン・外部素材なし |
- 空のシェイプレイヤーを作り、名前をROUTEにします。レイヤーのアンカーポイントと位置を[0, 0]、スケール100%、回転0度へ揃えます。
- ROUTEを選び、ペンツールで開いた曲線を描きます。塗りはなし、線は8px。パスが入ったシェイプグループをRoute、その中のパスをPathへ改名します。
- Routeグループ内のトランスフォームも、位置[0, 0]・アンカー[0, 0]・スケール100%・回転0度にします。
- ヌルを作ってCTRLと命名。「エフェクト」→「エクスプレッション制御」→「スライダー制御」を追加し、エフェクト名をProgressへ変更します。
- 別のシェイプレイヤーDOTを作り、楕円34×34pxと塗りを追加。楕円の中心とレイヤーのアンカーポイントを同じ位置に揃えます。
- DOTのレイヤー全体の「位置」のストップウォッチをOption/Alt+クリックし、次のコードを貼り付けます。
レイヤー名・グループ名・パス名・エフェクト名は、コードと正確に一致させます。今回の参照先は ROUTE → コンテンツ → Route → Path です。日本語UIの「パス 1」などのままなら、Pathへ改名するか、コード側をその名前へ合わせてください。
コピー用コード1:丸や矢印をパス上へ配置する
var route = thisComp.layer("ROUTE");
var path = route.content("Route").content("Path").path;
var u = clamp(thisComp.layer("CTRL").effect("Progress")(1) / 100, 0, 1);
route.toComp(path.pointOnPath(u));
Progress / 100 で、スライダーの0〜100をパスの0〜1へ変換しています。clamp(..., 0, 1) で範囲を制限するため、スライダーが範囲外でも始点・終点に留まります。
pointOnPath() が返すのはパス側の座標です。ここでは toComp() でコンポジション座標へ変換し、親のないDOTの位置へ渡しています。パスが入ったシェイプグループ内の追加変形までは、この式で変換していません。Routeグループの位置・スケール・回転は上の条件に揃えてください。
Progressを0〜100へ動かす
- CTRLのProgressを0にすると、丸がパスの始点に来ることを確認します。50と100でも位置を確認します。
- 0.5秒でProgress=0のキーフレームを作ります。
- 5.5秒へ移動し、Progress=100のキーフレームを作ります。
- 2つのキーをリニアにします。丸の位置にはキーを打たず、Progressだけで再生します。
配布例では冒頭・末尾を止めるため、0秒にも0、6秒にも100のキーを追加しています。0.5〜5.5秒の5秒間が移動部分です。元のパスを変形させない条件では、Progressを一定の速さで変えると、パスの長さに沿ってほぼ一定の速さで進みます。

配布AEPではPATH_BASIC_SOURCEを開いて編集します。記事の説明付き動画01_BASIC_PATHは、ソース全体を85%にして見出しと注記を添えたものです。
実践1:地図風ルートで、矢印の向きも追従させる
- DOTの代わりに、右向きの矢印を別シェイプレイヤーで作り、名前をARROWにします。
- アンカーポイントツール(Y)で、矢印の先端へアンカーポイントを合わせます。
- ARROWのレイヤー全体の「位置」へ、上の位置用コードを貼り付けます。
- 同じレイヤーの「回転」へ、次のコードを貼り付けます。
- ルートの後ろに道路風の線やブロックを配置し、始点と終点へSTART・GOALの目印を置きます。
コピー用コード2:カーブに合わせて矢印を回転
var route = thisComp.layer("ROUTE");
var path = route.content("Route").content("Path").path;
var u = clamp(thisComp.layer("CTRL").effect("Progress")(1) / 100, 0, 1);
var p = path.pointOnPath(u);
var a = route.toComp(p);
var b = route.toComp(p + path.tangentOnPath(u));
var v = b - a;
radiansToDegrees(Math.atan2(v[1], v[0]));
接線は、その場所でパスが進む方向です。この式では、パス上の点pと「p+接線」の2点をコンポジション座標へ変換し、その差から向きを求めます。Math.atan2() で角度を求め、radiansToDegrees() でAEの回転に使う度数へ変換しています。
位置と回転の両方が同じProgressを参照するので、移動位置と向きが揃います。ルートレイヤー自体を移動・拡大・回転しても、2点を変換することで向きを合わせられます。ただし、今回の式は親のない2Dレイヤー用です。3Dカメラや親レイヤーがある構成は、そのまま当てはめず座標系を揃えてください。

| 項目 | 作例の設定 |
|---|---|
| Progress | 0秒0/0.5秒0/5.5秒100/6秒100。全キーリニア |
| ARROW | 右向き・先端アンカー・塗りあり・親なし・2D |
| ROUTE | 開いたパス1本・線8px。グループ変形は初期値 |
| 背景 | AE内で作った架空の地図。実際の場所や道路の案内ではありません |
| 編集先 | PATH_ARROW_SOURCE。02_MAP_ROUTEでは85%で配置 |
実践2:描かれる線の先端へ、矢印を連動
- 矢印の位置・回転が動いている状態から、ROUTEのRouteグループを開きます。
- グループの「追加」→「パスのトリミング」を追加します。
- トリミングの開始を0%、オフセットを0度にします。対象パスは開いた1本だけにします。
- トリミングの「終了」へ、次の式を貼り付けます。
- CTRLのProgressを再生し、線の終点と矢印の先端が同じ場所に来ることを確認します。
コピー用コード3:線のトリミングも同じ進行率へ
clamp(thisComp.layer("CTRL").effect("Progress")(1), 0, 100);
トリミングの終了は0〜100%、pointOnPathの入力は0〜1です。同じProgressを、線にはそのまま、位置には100で割って渡すのがポイントです。線と矢印へ別々のキーを打たないので、タイミングのずれを減らせます。
配布例の薄い灰色の線は、未描画部分を見せる補助線GUIDEです。GUIDEのPathをROUTEのPathへ連動させ、ルートを描き直した場合も同じ形になるようにしています。演出に不要ならGUIDEを非表示にできます。
| 項目 | 設定 |
|---|---|
| トリミングの開始 | 0% |
| トリミングの終了 | Progressへ連動 |
| オフセット | 0度 |
| パス | 開いた1本。複数パスをまとめた場合は同じ対応になるとは限りません |
| 矢印の基準点 | 矢印の先端。中央アンカーのままだと先端位置がずれます |
| 編集先 | PATH_TRIM_SOURCE。03_DRAW_LINE_ARROWでは85%で配置 |

ルートを描き直したら、矢印はどうなる?

ROUTEのPathを編集すると、式が新しいパスから位置と接線を読み直します。位置キーへパスをコピーする方法と比べて、ルート変更後の貼り直しが要らないのが利点です。
一方、パスを描き直すと全長や長さの配分が変わります。同じ50%でも、画面上の同じ場所や同じ頂点を通るとは限りません。また、ルートレイヤーを縦横で違う比率に拡大した場合、コンポジション上の速さまで一定になる保証はありません。
うまく動かないときに確認するところ
| 症状 | 確認すること |
|---|---|
| 式の参照エラー | ROUTE/Route/Path/CTRL/Progressの名前が一致しているか |
| 丸がルートからずれる | Routeグループの位置・アンカー・スケール・回転、DOTの親と次元分割を確認 |
| 矢印の先端が線からずれる | アンカーが矢印の先端にあるか。位置式はレイヤー全体に設定する |
| 矢印が90度ずれる | 元の矢印が右向きか。上向きなど別の基準方向なら角度の補正が必要 |
| 逆向きに進む | パスの始点と終点、Progressのキーの方向を確認 |
| 角で急に回転する | 接線が不連続な角では向きが急変するため、ベジェハンドルで曲線を滑らかにする |
| 線と矢印のタイミングがずれる | 両方とも同じCTRLのProgressを参照し、トリミング開始0・オフセット0か確認 |
| 終点で始点へ戻る | 閉じたパスの0%と100%は同じ位置。今回の作例は開いたパス |
| マップ背景だけを動かしたい | 説明付きコンポ内の背景と、ルートを含むSOURCEを区別する |
作例プロジェクトをダウンロード
丸のパス移動・地図風ルート・線の先端追従と、3種類の比較を含む編集用プロジェクトです。
| 項目 | 内容 |
|---|---|
| ファイル | pas-pointonpath-v1.0.zip/100.2KB/v1.0 |
| 同梱内容 | 編集可能なAEP・はじめに.txt・コピー用コード |
| AE | 26.5×89/JavaScriptエクスプレッションエンジン |
| フォント | Hiragino Sans W6・Arial Bold。フォント本体は未同梱。ない場合は置換してください |
| 素材 | AE内の図形・文字のみ。外部参照・追加プラグイン不要 |
| 利用条件 | 学習・個人制作での利用と改変は可。商用利用は個別相談 |
商用利用のご相談はお問い合わせへ。ほかの表現はAEエクスプレッション集から探せます。


コメント