アニメーション

動的、手続き的、表現に基づくアニメーションを作成するための高度なアニメーションシステムで、単純なキーフレームを超えたものです。

アニメーションの種類

アニメーションシステムは、従来のキーフレームを超えた複数の種類をサポートしています。

  • 表現: フレームごとに評価されるJavaScriptの表現
  • 手続き的: 組み込みの手続き的アニメーションパターン
  • シーケンス: ステップベースの順次アニメーション
  • パス: ベジェパスに沿った動き

これらの高度なアニメーションは、要素の animations 配列プロパティで定義されます。

ノードアニメーションとキーフレーム

ノードアニメーション (animations 配列):

  • 手続き的、表現に基づく、またはパス追従アニメーション
  • 毎フレーム評価される
  • キーフレームよりも優先度が高い
  • キーフレームの値を上書きできる

キーフレーム (keyframes 配列):

  • 定義されたポイント間の単純なプロパティ補間
  • 優先度が低い
  • 予測可能で、編集が容易

アニメーションの優先度

複数のアニメーションメソッドが同じプロパティを対象とする場合:

  1. 最高: ノードアニメーション(表現、手続き的、パス、シーケンス)
  2. 中間: キーフレームアニメーション
  3. 最低: 静的プロパティ値
プロパティタイプ必須値の範囲説明
typestringtrue-expression | procedural | sequence | pathアニメーションのタイプ。
enabledbooleanfalse--アニメーションがアクティブかどうか。
targetstringtrue--アニメーションするプロパティパス(例: "x", "rotation", "scaleX")。
startTimenumberfalse--要素の開始に対するアニメーションの開始時間(秒単位)。
durationnumberfalse--アニメーションの持続時間(秒単位)。ループアニメーションの場合、これはループ期間です。
loopbooleanfalse--アニメーションがループするかどうか。
blendModestringfalse-replace | add | multiplyこのアニメーションが他のアニメーションとどのように組み合わさるか: 置き換え(上書き)、加算(合計)、乗算(スケール)。
blendWeightnumberfalse--このアニメーションの強さ/影響(0-1)。複数のアニメーションのブレンドに使用されます。

表現アニメーション

表現は、アニメーションコンテキスト変数にアクセスしながらフレームごとに評価されるJavaScriptコードです。

利用可能なコンテキスト変数

{
  time: number; // 現在の絶対時間(秒)
  localTime: number; // 要素開始に対する時間
  duration: number; // 要素の持続時間
  progress: number; // 正規化された進行状況(0-1)
  index: number; // グループ内の要素インデックス
  total: number; // グループ内の総要素数
  fps: number; // 秒間フレーム数
  width: number; // キャンバス幅
  height: number; // キャンバス高さ
  value: any; // 現在のプロパティ値
}

表現の例

Math関数を使用したバウンスアニメーション:

expressionAnimation.json
{
"id": "element-1",
"type": "Image",
"start": 0,
"duration": 5,
"animations": [
  {
    "type": "expression",
    "target": "y",
    "enabled": true,
    "expression": "100 + Math.abs(Math.sin(localTime * 3)) * 200",
    "startTime": 0,
    "duration": 5,
    "loop": true
  }
]
}

複雑な表現

複数の効果を組み合わせる:

complexExpression.json
{
"animations": [
  {
    "type": "expression",
    "target": "rotation",
    "expression": "(localTime * 2 * Math.PI / duration) + Math.sin(localTime * 4) * 0.1",
    "loop": true
  },
  {
    "type": "expression",
    "target": "scaleX",
    "expression": "1 + Math.sin(localTime * 5) * 0.2",
    "loop": true
  }
]
}

手続き的アニメーション

設定可能なパラメータを持つ組み込みのアニメーションパターン。

手続き的タイプ

  • wiggle: ランダムな振動(ハンドヘルドカメラ効果に便利)
  • wave: サイン/コサイン波の動き
  • bounce: 弾性的なバウンス効果
  • pulse: リズミカルなスケーリング

ウィグルの例

wiggleAnimation.json
{
"animations": [
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "enabled": true,
    "frequency": 2,
    "amplitude": 0.1,
    "loop": true
  }
]
}

シーケンスアニメーション

特定の間隔で値を変えるステップベースのアニメーション。

プロパティタイプ必須値の範囲説明
valuesarraytrue--ステップを通過する値の配列。
stepDurationnumbertrue--各ステップの持続時間(秒単位)。
loopbooleanfalse--シーケンスをループするかどうか。

シーケンスの例

異なるサイズでテキストをサイクルする:

sequenceAnimation.json
{
"animations": [
  {
    "type": "sequence",
    "target": "fontSize",
    "enabled": true,
    "values": [24, 32, 40, 32, 24],
    "stepDuration": 0.5,
    "loop": true
  }
]
}

パスアニメーション

ベジェ曲線パスに沿って要素をアニメーションさせる。

プロパティタイプ必須値の範囲説明
pathstring | arraytrue--SVGパスデータ(d属性)またはパスポイントの配列。
autoRotatebooleanfalse--パスの接線に従って要素を自動的に回転させるかどうか。
durationnumbertrue--全パスを完了するのにかかる時間。

パスの例

円運動:

pathAnimation.json
{
"animations": [
  {
    "type": "path",
    "target": "position",
    "enabled": true,
    "path": "M 100,100 a 200,200 0 1,1 0,1 Z",
    "autoRotate": true,
    "duration": 4,
    "loop": true
  }
]
}

プロパティパス構文

target プロパティは、ドット表記を使用してネストされたプロパティを指定します:

  • 単純: "x", "y", "rotation"
  • ネスト: "scale.x", "position.y"
  • 配列: "colors[0]", "points[2].x"

ターゲット解決の例

{
  "target": "x"              // 要素のx位置
  "target": "scaleX"         // 水平スケール
  "target": "alpha"          // 不透明度
  "target": "fill.color"     // 塗りつぶし色(塗りつぶしがオブジェクトの場合)
  "target": "points[0].x"    // 最初の点のx座標
}

ブレンドモード

複数のアニメーションが同じプロパティを対象とする場合の組み合わせ方法を制御します:

置き換え(デフォルト)

{
  "blendMode": "replace",
  "blendWeight": 1.0
}

プロパティ値を完全に置き換えます。

加算

{
  "blendMode": "add",
  "blendWeight": 0.5
}

既存の値に加算します(重み付け)。オフセットの蓄積に便利です。

乗算

{
  "blendMode": "multiply",
  "blendWeight": 1.0
}

既存の値を乗算します。スケーリング効果に便利です。

複数アニメーションの例

異なるアニメーションタイプを組み合わせる:

multipleAnimations.json
{
"id": "animated-element",
"type": "Shape",
"animations": [
  {
    "type": "expression",
    "target": "x",
    "expression": "width / 2 + Math.sin(localTime * 2) * 300",
    "blendMode": "replace",
    "loop": true
  },
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "frequency": 3,
    "amplitude": 0.2,
    "blendMode": "add",
    "blendWeight": 0.5
  },
  {
    "type": "sequence",
    "target": "alpha",
    "values": [1, 0.8, 1],
    "stepDuration": 0.3,
    "loop": true,
    "blendMode": "multiply"
  }
],
"keyframes": [
  {
    "id": "kf-1",
    "time": 0,
    "stateObj": { "scaleX": 1 }
  },
  {
    "id": "kf-2",
    "time": 2,
    "stateObj": { "scaleX": 1.5 }
  }
]
}

この例では:

  • 表現が水平方向の位置を制御(置き換えモード)
  • 手続き的ウィグルが微妙な回転の変化を追加
  • シーケンスが不透明度をパルスさせる
  • キーフレームが要素をスケーリング(最低優先度)

重要な注意事項

表現サンドボックス

  • 表現はセキュリティのために制限されたコンテキストで実行されます
  • アニメーションコンテキスト変数へのアクセスのみ
  • DOM、外部ライブラリ、またはNode.js APIへのアクセスはできません
  • 評価エラーが発生するとアニメーションが無効になります

パフォーマンス

  • 表現: 毎フレーム評価される - シンプルに保つ
  • 手続き的: 最適化された組み込み関数 - 非常に効率的
  • シーケンス: 最小限のオーバーヘッド、離散的な変更に適している
  • パス: 中程度のコスト、パスの複雑さに依存

タイミング

  • startTime および duration は要素の start 時間に対して相対的です
  • 表現内の localTime は要素が始まるときに0から始まります
  • アニメーションは要素の全体の duration 境界を尊重します

デバッグ

  • アニメーションが機能しない場合は、以下を確認してください:
    • enabled: true
    • 要素に target プロパティが存在する
    • 表現の構文が有効なJavaScriptである
    • startTime が要素の持続時間内にある
    • プロパティパスのタイプミスがない

一般的な使用例

スムーズなフォロワー効果

{
  "type": "expression",
  "target": "x",
  "expression": "value + (targetX - value) * 0.1"
}

弾性的なバウンス

{
  "type": "expression",
  "target": "scaleY",
  "expression": "1 + Math.exp(-localTime * 3) * Math.cos(localTime * 8) * 0.5"
}

カメラの揺れ

{
  "type": "procedural",
  "proceduralType": "wiggle",
  "target": "x",
  "frequency": 10,
  "amplitude": 5
}

階段状のアニメーション(グループ内)

{
  "type": "expression",
  "target": "alpha",
  "expression": "Math.max(0, Math.min(1, (localTime - index * 0.1) * 2))"
}