2024年1月20日

CSSアニメーション

CSSアニメーションを使用すると、JavaScriptを全く使用せずに簡単なアニメーションを作成できます。

JavaScriptを使用してCSSアニメーションを制御し、少ないコードでさらに優れたアニメーションを作成できます。

CSSトランジション

CSSトランジションの考え方はシンプルです。プロパティと、その変更をどのようにアニメーション化する必要があるかを記述します。プロパティが変更されると、ブラウザはアニメーションを描画します。

つまり、プロパティを変更するだけで、滑らかなトランジションはブラウザによって行われます。

たとえば、以下のCSSは、`background-color`の変更を3秒間アニメーション化します。

.animated {
  transition-property: background-color;
  transition-duration: 3s;
}

要素に`.animated`クラスがある場合、`background-color`の変更は3秒間アニメーション化されます。

以下のボタンをクリックして、背景をアニメーション化します。

<button id="color">Click me</button>

<style>
  #color {
    transition-property: background-color;
    transition-duration: 3s;
  }
</style>

<script>
  color.onclick = function() {
    this.style.backgroundColor = 'red';
  };
</script>

CSSトランジションを記述するためのプロパティは4つあります。

  • transition-property
  • transition-duration
  • transition-timing-function
  • transition-delay

これらについては後ほど説明しますが、ここでは、共通の`transition`プロパティを使用すると、`property duration timing-function delay`の順序でまとめて宣言できること、また、複数のプロパティを一度にアニメーション化できることに注意してください。

たとえば、このボタンは`color`と`font-size`の両方をアニメーション化します。

<button id="growing">Click me</button>

<style>
#growing {
  transition: font-size 3s, color 2s;
}
</style>

<script>
growing.onclick = function() {
  this.style.fontSize = '36px';
  this.style.color = 'red';
};
</script>

それでは、アニメーションのプロパティを1つずつ見ていきましょう。

transition-property

`transition-property`には、アニメーション化するプロパティのリストを記述します。たとえば、`left`、`margin-left`、`height`、`color`などです。または、"すべてのプロパティをアニメーション化する"という意味の`all`を記述することもできます。

アニメーション化できないプロパティがあることに注意してください。ただし、一般的に使用されるほとんどのプロパティはアニメーション化可能です

transition-duration

`transition-duration`では、アニメーションの時間を指定できます。時間はCSS時間形式で指定する必要があります。秒の場合は`s`、ミリ秒の場合は`ms`を使用します。

transition-delay

`transition-delay`では、アニメーションの*開始前*の遅延を指定できます。たとえば、`transition-delay`が`1s`で`transition-duration`が`2s`の場合、アニメーションはプロパティの変更から1秒後に開始され、合計時間は2秒になります。

負の値も可能です。その場合、アニメーションはすぐに表示されますが、アニメーションの開始点は指定された値(時間)の後になります。たとえば、`transition-delay`が`-1s`で`transition-duration`が`2s`の場合、アニメーションは中間点から開始され、合計時間は1秒になります。

ここでは、CSSの`translate`プロパティを使用して、数字を`0`から`9`にシフトするアニメーションを示します。

結果
script.js
style.css
index.html
stripe.onclick = function() {
  stripe.classList.add('animate');
};
#digit {
  width: .5em;
  overflow: hidden;
  font: 32px monospace;
  cursor: pointer;
}

#stripe {
  display: inline-block
}

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 9s;
  transition-timing-function: linear;
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  Click below to animate:

  <div id="digit"><div id="stripe">0123456789</div></div>

  <script src="script.js"></script>
</body>

</html>

`transform`プロパティは次のようにアニメーション化されます。

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 9s;
}

上記の例では、JavaScriptが要素に`.animate`クラスを追加し、アニメーションが開始されます。

stripe.classList.add('animate');

トランジションの途中から、たとえば現在の秒に対応する正確な数値から、負の`transition-delay`を使用して開始することもできます。

ここで数字をクリックすると、現在の秒からアニメーションが開始されます。

結果
script.js
style.css
index.html
stripe.onclick = function() {
  let sec = new Date().getSeconds() % 10;
  stripe.style.transitionDelay = '-' + sec + 's';
  stripe.classList.add('animate');
};
#digit {
  width: .5em;
  overflow: hidden;
  font: 32px monospace;
  cursor: pointer;
}

#stripe {
  display: inline-block
}

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 9s;
  transition-timing-function: linear;
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  Click below to animate:
  <div id="digit"><div id="stripe">0123456789</div></div>

  <script src="script.js"></script>
</body>
</html>

JavaScriptは1行追加することでこれを実現します。

stripe.onclick = function() {
  let sec = new Date().getSeconds() % 10;
  // for instance, -3s here starts the animation from the 3rd second
  stripe.style.transitionDelay = '-' + sec + 's';
  stripe.classList.add('animate');
};

transition-timing-function

タイミング関数は、アニメーションプロセスがタイムラインに沿ってどのように分散されるかを記述します。ゆっくりと開始して速くなるのか、それともその逆か。

最初は最も複雑なプロパティのように見えますが、少し時間をかければ非常にシンプルになります。

このプロパティは、ベジェ曲線またはステップの2種類の値を受け入れます。ベジェ曲線の方がよく使用されるため、まずはそこから見ていきましょう。

ベジェ曲線

タイミング関数は、以下の条件を満たす4つの制御点を持つベジェ曲線として設定できます。

  1. 最初の制御点:`(0,0)`。
  2. 最後の制御点:`(1,1)`。
  3. 中間点の場合、`x`の値は`0..1`の範囲内でなければならず、`y`は何でもかまいません。

CSSにおけるベジェ曲線の構文:`cubic-bezier(x2, y2, x3, y3)`。最初の制御点は`(0,0)`に固定され、4番目の制御点は`(1,1)`に固定されているため、2番目と3番目の制御点のみを指定する必要があります。

タイミング関数は、アニメーションプロセスの速度を記述します。

  • `x`軸は時間です。`0`は開始時、`1`は`transition-duration`の終了時です。
  • `y`軸はプロセスの完了度を指定します。`0`はプロパティの開始値、`1`は最終値です。

最も簡単なケースは、アニメーションが同じ線形速度で均一に進む場合です。これは、曲線`cubic-bezier(0, 0, 1, 1)`で指定できます。

この曲線は次のようになります。

…ご覧のとおり、これはただの直線です。時間(`x`)が経過するにつれて、アニメーションの完了(`y`)は着実に`0`から`1`に進みます。

以下の例では、電車が一定の速度で左から右に移動します(クリックしてください)。

結果
style.css
index.html
.train {
  position: relative;
  cursor: pointer;
  width: 177px;
  height: 160px;
  left: 0;
  transition: left 5s cubic-bezier(0, 0, 1, 1);
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='450px'">

</body>

</html>

CSSの`transition`はこの曲線に基づいています。

.train {
  left: 0;
  transition: left 5s cubic-bezier(0, 0, 1, 1);
  /* click on a train sets left to 450px, thus triggering the animation */
}

…では、減速する電車をどのように表示すればよいでしょうか?

別のベジェ曲線`cubic-bezier(0.0, 0.5, 0.5 ,1.0)`を使用できます。

グラフ

ご覧のとおり、プロセスは高速に開始されます。曲線は高く舞い上がり、その後は徐々に速度が低下します。

タイミング関数の動作を確認してください(電車をクリックしてください)。

結果
style.css
index.html
.train {
  position: relative;
  cursor: pointer;
  width: 177px;
  height: 160px;
  left: 0px;
  transition: left 5s cubic-bezier(0.0, 0.5, 0.5, 1.0);
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='450px'">

</body>

</html>

CSS

.train {
  left: 0;
  transition: left 5s cubic-bezier(0, .5, .5, 1);
  /* click on a train sets left to 450px, thus triggering the animation */
}

組み込みの曲線はいくつかあります。`linear`、`ease`、`ease-in`、`ease-out`、`ease-in-out`です。

`linear`は`cubic-bezier(0, 0, 1, 1)`の省略形です。これは、上記で説明した直線です。

他の名前は、以下の`cubic-bezier`の省略形です。

`ease`* ease-in ease-out ease-in-out
(0.25, 0.1, 0.25, 1.0) (0.42, 0, 1.0, 1.0) (0, 0, 0.58, 1.0) (0.42, 0, 0.58, 1.0)

`*` - デフォルトでは、タイミング関数が指定されていない場合、`ease`が使用されます。

そのため、減速する電車には`ease-out`を使用できます。

.train {
  left: 0;
  transition: left 5s ease-out;
  /* same as transition: left 5s cubic-bezier(0, .5, .5, 1); */
}

ただし、少し異なって見えます。

ベジェ曲線を使用すると、アニメーションが範囲を超える可能性があります。

曲線の制御点は、負の値や非常に大きな値など、任意の`y`座標を持つことができます。その場合、ベジェ曲線も非常に低くまたは高く拡張され、アニメーションが通常の範囲を超えてしまいます。

以下の例では、アニメーションコードは次のとおりです。

.train {
  left: 100px;
  transition: left 5s cubic-bezier(.5, -1, .5, 2);
  /* click on a train sets left to 450px */
}

プロパティ`left`は`100px`から`400px`にアニメーション化する必要があります。

ただし、電車をクリックすると、次のようになります。

  • まず、電車が*後退*します。`left`が`100px`未満になります。
  • 次に、`400px`よりも少し आगे बढ़ります。
  • そして、再び`400px`に戻ります。
結果
style.css
index.html
.train {
  position: relative;
  cursor: pointer;
  width: 177px;
  height: 160px;
  left: 100px;
  transition: left 5s cubic-bezier(.5, -1, .5, 2);
}
<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <img class="train" src="https://js.cx/clipart/train.gif" onclick="this.style.left='400px'">

</body>

</html>

なぜこうなるのかは、指定されたベジェ曲線のグラフを見れば明らかです。

2番目の点の`y`座標をゼロより下に移動し、3番目の点の`y`座標を`1`より大きくしたため、曲線が"通常の"象限から外れています。`y`は"標準の"範囲`0..1`から外れています。

ご存知のとおり、`y`は"アニメーションプロセスの完了"を測定します。値`y = 0`は開始プロパティ値に対応し、`y = 1`は終了値に対応します。したがって、`y<0`の値はプロパティを開始`left`よりも先に移動し、`y>1`の値は最終`left`を超えて移動します。

これは確かに"ソフトな"バリアントです。`y`値を`-99`や`99`のように設定すると、電車は範囲からはるかに大きく飛び出します。

しかし、特定のタスクのためのベジェ曲線をどのように作成すればよいでしょうか?多くのツールがあります。

  • たとえば、https://cubic-bezier.comのサイトで作成できます。
  • ブラウザの開発者ツールにも、CSSのベジェ曲線を編集するための特別なサポートが用意されています。
    1. F12(Mac:Cmd+Opt+I)で開発者ツールを開きます。
    2. `要素`タブを選択し、右側にある`スタイル`サブパネルに注目します。
    3. `cubic-bezier`という単語を含むCSSプロパティには、この単語の前にアイコンが表示されます。
    4. このアイコンをクリックして、曲線を編集します。

ステップ

タイミング関数`steps(ステップ数[, start/end])`を使用すると、トランジションを複数のステップに分割できます。

数字の例で見てみましょう。

ここでは、アニメーションなしの数字のリストをソースとして示します。

結果
style.css
index.html
#digit {
  border: 1px solid red;
  width: 1.2em;
}

#stripe {
  display: inline-block;
  font: 32px monospace;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  <div id="digit"><div id="stripe">0123456789</div></div>

</body>
</html>

HTMLでは、数字のストライプが固定長の`<div id="digits">`で囲まれています。

<div id="digit">
  <div id="stripe">0123456789</div>
</div>

`#digit`divは固定幅と境界線があるため、赤いウィンドウのように見えます。

タイマーを作成します。数字は1つずつ、個別の方法で表示されます。

これを実現するために、`overflow: hidden`を使用して`#digit`の外側にある`#stripe`を非表示にし、`#stripe`をステップごとに左にシフトします。

各数字に1ステップずつ、9ステップあります。

#stripe.animate  {
  transform: translate(-90%);
  transition: transform 9s steps(9, start);
}

`steps(9, start)`の最初の引数はステップ数です。変換は9つのパート(それぞれ10%)に分割されます。時間間も自動的に9つのパートに分割されるため、`transition: 9s`はアニメーション全体で9秒、つまり数字ごとに1秒になります。

2番目の引数は、`start`または`end`のいずれかの単語です。

`start`は、アニメーションの開始時に最初のステップをすぐに実行する必要があることを意味します。

動作中

結果
style.css
index.html
#digit {
  width: .5em;
  overflow: hidden;
  font: 32px monospace;
  cursor: pointer;
}

#stripe {
  display: inline-block
}

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 9s;
  transition-timing-function: steps(9, start);
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  Click below to animate:

  <div id="digit"><div id="stripe">0123456789</div></div>

  <script>
    digit.onclick = function() {
      stripe.classList.add('animate');
    }
  </script>


</body>

</html>

数字をクリックすると、すぐに`1`(最初のステップ)に変更され、次の秒の開始時に変更されます。

プロセスは次のように進行します。

  • `0s` - `-10%`(最初の変更は1秒目の開始時、すぐに)
  • `1s` - `-20%`
  • `8s` - `-90%`
  • (最後の秒は最終値を示します)。

ここでは、`steps`で`start`が使用されているため、最初の変更はすぐに発生しました。

代替値であるendは、変更が各秒の開始時ではなく、終了時に適用されることを意味します。

つまり、steps(9, end)の処理は次のようになります。

  • 0秒0 (最初の1秒間は何も変わりません)
  • 1秒-10% (最初の変更は1秒目の終わりに発生します)
  • 2秒-20%
  • 9秒-90%

steps(9, end)の動作例です(最初の数字が変わる前のポーズに注目してください)

結果
style.css
index.html
#digit {
  width: .5em;
  overflow: hidden;
  font: 32px monospace;
  cursor: pointer;
}

#stripe {
  display: inline-block
}

#stripe.animate {
  transform: translate(-90%);
  transition-property: transform;
  transition-duration: 9s;
  transition-timing-function: steps(9, end);
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
</head>

<body>

  Click below to animate:

  <div id="digit"><div id="stripe">0123456789</div></div>

  <script>
    digit.onclick = function() {
      stripe.classList.add('animate');
    }
  </script>


</body>

</html>

steps(...)には、いくつかの定義済み shorthand もあります。

  • step-startsteps(1, start)と同じです。つまり、アニメーションはすぐに開始し、1ステップで完了します。そのため、アニメーションがないかのように、すぐに開始して終了します。
  • step-endsteps(1, end)と同じです。transition-durationの最後に1ステップでアニメーションを実行します。

これらの値は、実際のアニメーションではなく、1ステップの変更を表すため、めったに使用されません。完全を期すためにここで言及しています。

イベント: “transitionend”

CSSアニメーションが終了すると、transitionendイベントがトリガーされます。

これは、アニメーションの完了後にアクションを実行するために広く使用されています。また、アニメーションを結合することもできます。

たとえば、以下の例の船は、クリックされるたびに左右に increasingly 動きます。

アニメーションは、トランジションが終了するたびに再実行され、方向を反転させる関数goによって開始されます。

boat.onclick = function() {
  //...
  let times = 1;

  function go() {
    if (times % 2) {
      // sail to the right
      boat.classList.remove('back');
      boat.style.marginLeft = 100 * times + 200 + 'px';
    } else {
      // sail to the left
      boat.classList.add('back');
      boat.style.marginLeft = 100 * times - 200 + 'px';
    }

  }

  go();

  boat.addEventListener('transitionend', function() {
    times++;
    go();
  });
};

transitionendのイベントオブジェクトには、いくつかの特定のプロパティがあります。

event.propertyName
アニメーションが終了したプロパティ。複数のプロパティを同時にアニメーション化する場合は便利です。
event.elapsedTime
アニメーションにかかった時間(秒単位)。transition-delayは含まれません。

キーフレーム

@keyframes CSSルールを使用して、複数の単純なアニメーションを結合できます。

これは、アニメーションの「名前」とルール(何を、いつ、どこでアニメーション化するか)を指定します。次に、animationプロパティを使用して、アニメーションを要素にアタッチし、追加のパラメーターを指定できます。

説明付きの例を次に示します。

<div class="progress"></div>

<style>
  @keyframes go-left-right {        /* give it a name: "go-left-right" */
    from { left: 0px; }             /* animate from left: 0px */
    to { left: calc(100% - 50px); } /* animate to left: 100%-50px */
  }

  .progress {
    animation: go-left-right 3s infinite alternate;
    /* apply the animation "go-left-right" to the element
       duration 3 seconds
       number of times: infinite
       alternate direction every time
    */

    position: relative;
    border: 2px solid green;
    width: 50px;
    height: 20px;
    background: lime;
  }
</style>

@keyframesに関する記事は多数あり、詳細な仕様書もあります。

サイト上のすべてが常に動いている場合を除き、@keyframesはそれほど頻繁には必要ないでしょう。

パフォーマンス

ほとんどのCSSプロパティは数値であるため、アニメーション化できます。たとえば、widthcolorfont-sizeはすべて数値です。これらをアニメーション化すると、ブラウザはこれらの数値をフレームごとに徐々に変更し、スムーズな効果を作成します。

ただし、CSSプロパティによって変更のコストが異なるため、すべてのアニメーションが思いどおりにスムーズに見えるとは限りません。

より技術的な詳細として、スタイルが変更されると、ブラウザは新しい外観をレンダリングするために3つのステップを実行します。

  1. レイアウト: 各要素のジオメトリと位置を再計算し、次に
  2. ペイント: 背景、色などを含め、すべてがどのように見えるかを再計算し、
  3. コンポジット: 最終結果を画面上のピクセルにレンダリングし、CSS変換が存在する場合は適用します。

CSSアニメーション中は、このプロセスがフレームごとに繰り返されます。ただし、colorのようにジオメトリや位置に影響を与えないCSSプロパティは、レイアウトステップをスキップする場合があります。colorが変更された場合、ブラウザは新しいジオメトリを計算せず、ペイント→コンポジットに進みます。また、コンポジットに直接進むプロパティもいくつかあります。CSSプロパティのより長いリストと、それらがどのステージをトリガーするかは、https://csstriggers.comで見つけることができます。

計算には、特に要素が多くレイアウトが複雑なページでは、時間がかかる場合があります。また、遅延は実際にはほとんどのデバイスで目に見え、「ぎくしゃくした」、滑らかでないアニメーションにつながります。

レイアウトステップをスキップするプロパティのアニメーションは高速です。ペイントもスキップされるとさらに良くなります。

transformプロパティは、次の理由から最適な選択肢です。

  • CSS変換は、ターゲット要素ボックス全体に影響を与えます(回転、反転、ストレッチ、シフト)。
  • CSS変換は、隣接要素に影響を与えません。

…そのため、ブラウザは既存のレイアウトとペイントの計算に加えて、コンポジットステージでtransformを適用します。

言い換えれば、ブラウザはレイアウト(サイズ、位置)を計算し、ペイントステージで色、背景などでペイントし、次に必要に応じて要素ボックスにtransformを適用します。

transformプロパティの変更(アニメーション)は、レイアウトとペイントのステップをトリガーしません。さらに、ブラウザはCSS変換にグラフィックアクセラレータ(CPUまたはグラフィックカード上の特別なチップ)を活用するため、非常に効率的です。

幸いなことに、transformプロパティは非常に強力です。要素にtransformを使用することで、回転、反転、ストレッチ、縮小、移動など、さまざまな操作を実行できます。そのため、left/margin-leftプロパティの代わりにtransform: translateX(…)を使用したり、要素のサイズを増やすためにtransform: scaleを使用したりできます。

opacityプロパティもレイアウトをトリガーしません(Mozilla Geckoではペイントもスキップします)。表示/非表示またはフェードイン/フェードアウト効果に使用できます。

transformopacityを組み合わせることで、通常、ほとんどのニーズを満たすことができ、滑らかで見た目も良いアニメーションを提供できます。

たとえば、ここで#boat要素をクリックすると、transform: translateX(300px)opacity: 0を持つクラスが追加され、300px右に移動して消えます。

<img src="https://js.cx/clipart/boat.png" id="boat">

<style>
#boat {
  cursor: pointer;
  transition: transform 2s ease-in-out, opacity 2s ease-in-out;
}

.move {
  transform: translateX(300px);
  opacity: 0;
}
</style>
<script>
  boat.onclick = () => boat.classList.add('move');
</script>

@keyframesを使用した、より複雑な例を次に示します。

<h2 onclick="this.classList.toggle('animated')">click me to start / stop</h2>
<style>
  .animated {
    animation: hello-goodbye 1.8s infinite;
    width: fit-content;
  }
  @keyframes hello-goodbye {
    0% {
      transform: translateY(-60px) rotateX(0.7turn);
      opacity: 0;
    }
    50% {
      transform: none;
      opacity: 1;
    }
    100% {
      transform: translateX(230px) rotateZ(90deg) scale(0.5);
      opacity: 0;
    }
  }
</style>

まとめ

CSSアニメーションを使用すると、1つまたは複数のCSSプロパティをスムーズに(または段階的に)アニメーション化して変更できます。

ほとんどのアニメーショんタスクに適しています。JavaScriptを使用してアニメーションを作成することもできます。次の章では、それについて説明します。

JavaScriptアニメーションと比較したCSSアニメーションの制限

メリット
  • 単純なことは単純にできる。
  • CPUに高速で軽量。
デメリット
  • JavaScriptアニメーションは柔軟です。要素の「爆発」など、あらゆるアニメーションロジックを実装できます。
  • プロパティの変更だけではありません。アニメーションの一部としてJavaScriptで新しい要素を作成できます。

この章の最初の例では、font-sizeleftwidthheightなどをアニメーション化しました。実際のプロジェクトでは、パフォーマンスを向上させるために、transform: scale()transform: translate()を使用する必要があります。

ほとんどのアニメーションは、この章で説明したようにCSSを使用して実装できます。また、transitionendイベントを使用すると、アニメーションの後にJavaScriptを実行できるため、コードと適切に統合されます。

しかし、次の章では、より複雑なケースをカバーするために、いくつかのJavaScriptアニメーションを作成します。

タスク

重要度: 5

下の図のようなアニメーションを表示します(飛行機をクリックします)

  • 画像はクリックすると40x24pxから400x240px(10倍)に拡大します。
  • アニメーションには3秒かかります。
  • 最後に「完了!」と出力します。
  • アニメーションプロセス中に、飛行機がさらにクリックされる場合があります。それらは何も「壊す」べきではありません。

タスクのサンドボックスを開きます。

widthheightの両方をアニメーション化するCSS

/* original class */

#flyjet {
  transition: all 3s;
}

/* JS adds .growing */
#flyjet.growing {
  width: 400px;
  height: 240px;
}

transitionendはプロパティごとに1回、2回トリガーされることに注意してください。そのため、追加のチェックを実行しないと、メッセージが2回表示されます。

サンドボックスでソリューションを開きます。

重要度: 5

前のタスク飛行機のアニメーション(CSS)のソリューションを変更して、飛行機が元のサイズ400x240pxよりも大きく成長し(飛び出し)、元のサイズに戻します。

どのように見えるかはこちらです(飛行機をクリックしてください)

前のタスクのソリューションをソースとして使用します。

そのアニメーションに適したベジェ曲線を選択する必要があります。飛行機が「飛び出す」ためには、どこかでy>1である必要があります。

たとえば、cubic-bezier(0.25, 1.5, 0.75, 1.5)のように、両方の制御点をy>1にすることができます。

グラフ

サンドボックスでソリューションを開きます。

重要度: 5

アニメーションで成長する円を表示する関数showCircle(cx, cy, radius)を作成します。

  • cx,cyは、円のの中心のウィンドウ相対座標です。
  • radiusは円の半径です。

下のボタンをクリックして、どのように見えるかを確認してください

ソースドキュメントには、適切なスタイルの円の例があるため、タスクはアニメーションを正しく実行することです。

タスクのサンドボックスを開きます。

タスクアニメーションサークルでは、アニメーションで成長する円が表示されます。

ここで、円だけでなく、その中にメッセージを表示する必要があるとしましょう。メッセージは、アニメーションが完了した後(円が完全に成長した後)に表示される必要があります。そうでないと、見栄えが悪くなります。

タスクの解決策では、関数showCircle(cx, cy, radius)は円を描画しますが、いつ準備ができたかを追跡する方法を提供しません。

アニメーションの完了時に呼び出されるコールバック引数:showCircle(cx, cy, radius, callback)を追加します。callbackは、引数として円<div>を受け取る必要があります。

例を次に示します

showCircle(150, 150, 100, div => {
  div.classList.add('message-ball');
  div.append("Hello, world!");
});

デモ

タスクアニメーションサークルのソリューションをベースとして使用します。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善のための提案がある場合は、コメントする代わりに、GitHub issueまたはプルリクエストを送信してください。
  • 記事の内容が理解できない場合は、詳しく説明してください。
  • 数語のコードを挿入するには、<code>タグを使用し、数行の場合は<pre>タグで囲み、10行を超える場合はサンドボックス(plnkrjsbincodepen…)を使用してください。