2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

記事投稿キャンペーン 「2024年!初アウトプットをしよう」

frameCount・剰余演算を使った p5.js でのループアニメーション:アニメーションの最初と最後に空白の時間を作る

Last updated at Posted at 2023-12-31

今回の内容

p5.js でループするアニメーションを作る際に、frameCount と剰余演算を組み合わせたものをよく使うのですが、それに関連した内容です。

直近で、以下のようなアニメーション(イージングを適用したループアニメーション)を作ろうとした中で、試してみていた内容です。

プログラムの内容など

プログラム例を紹介してから、少し補足を書いてみます。

実装1

まずは、1つ目のプログラム全体を掲載します。

function setup() {
  createCanvas(550, 400);
  noStroke();
  fill(100, 120, 210);
}

function draw() {
  background(220);

  let f = frameCount % 300;

  f = (() => {
    if (f < 45) {
      return 0;
    }
    if (f > 200) return 1;
    return map(f, 45, 200, 0, 1);
  })();

  // console.log(f);
  circle(lerp(0, width, easing(f)), height / 2, 80);
}

function easing(t) {
  // https://easings.net/ja#easeInExpo
  return t === 0 ? 0 : pow(2, 10 * t - 10);
}

ループする時間間隔は frameCount % 300 の部分の、300フレーム分毎の時間になります。

そして、その 300フレームの中では、45フレーム目まではゼロ、200フレームより大きいところは 1、その間では 0 から 1 までを線形増加する値を作っています。この値をもとに、lerp() と easing() を使ったイージングの実装を行っています。

上記の 0 にした部分と 1 にした部分は、イージングが適用された動きの開始時と終了時の、それぞれの位置に静止した状態になります。ここで、動きが止まる空白の時間を作っています。

イージングの関数について

イージングの関数の部分は、有名どころの以下を見て実装しました。

●イージング関数チートシート
 https://easings.net/ja

実装2

上に書いていたものとは、別の実装を試したものが以下になります。

function setup() {
  createCanvas(550, 400);
  noStroke();
  fill(100, 120, 210);
}

function draw() {
  background(220);

  let f = frameCount % 200;

  f = f < 120 ? 0 : map(f, 120, 200, 0, 2);
  f = constrain(f, 0, 1);
  // console.log(f);

  circle(lerp(0, width, easing(f)), height / 2, 80);
}

function easing(t) {
  // https://easings.net/ja#easeInExpo
  return t === 0 ? 0 : pow(2, 10 * t - 10);
}

上記では、200 フレームのループが行われる中で、120フレームより小さい部分は 0 の値にするようにしました。そして、それより大きい値のところは、0 から 2 まで線形増加するようにしつつも、constrain() を使って上限の値を 1 に制限してみました。

これにより、上記の線形増加している部分で、1 から 2 の間の部分が全て 1 の値になります。
この事例でも 1つ目の実装と同じく、動きのある区間の前後それぞれおで、動きのない空白の時間を作っています。

そして、2つ目の実装例でも、1つ目の実装例と同じようにイージングを適用しています。

おわりに

自分が p5.js のアニメーション実装でよく使う frameCount と剰余演算を使ったループアニメーションの処理に関する話を書いてみました。

実装方法は他にもいろいろあると思いますので、他の実装も試していければと思っています。

実装1 の即時実行関数式の部分について

1つ目の実装例について、即時実行関数式を使った部分があります。
ここでの書き方は、最近見かけた以下の記事を参考にしました。

ちなみに以下の記事の概要は、多段の入れ子の三項演算子・条件文を避ける、という方向の内容でした。

●Stop nesting ternaries in JavaScript | Sonar
 https://www.sonarsource.com/blog/stop-nesting-ternaries-javascript/

image.png

image.png

// 関数
function animalName(pet) {
  if (pet.canBark() && pet.isScary()) { return "wolf"; }
  if (pet.canBark()) return "dog";
  if (pet.canMeow()) return "cat";
  return "probably a bunny";
}

// 即時実行関数式
const animalName = (() => {
  if (pet.canBark() && pet.isScary()) { return "wolf"; }
  if (pet.canBark()) return "dog";
  if (pet.canMeow()) return "cat";
  return "probably a bunny";
})();
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?