以前、Tweenアニメーションをいくつか試作した際に、複数のライブラリを試してみました。
例えば、その 1つは以下の「anime.js」であったり、他には、今回の記事で扱う「p5.tween」やその他にも 2つか 3つのライブラリがありました。
●p5.js と anime.js を組み合わせた Tweenアニメーション - Qiita
https://qiita.com/youtoy/items/361282f1113d88ff5f05
その中で、「p5.tween」については記事を書いていなかったので、今回、記事を書いてみました。
公式ページは以下になります。
●Milchreis/p5.tween: Tween library for P5.js
https://github.com/Milchreis/p5.tween
動作している様子
今回実装したものが動作している様子を最初に示します。
4つのボールがバウンドする、というものです。
この時の、円の色・初期位置の高さ・大きさは、ランダムに決めています。
そのため処理を再実行した際に、それらが変化しているのが分かるかと思います。
元にした公式サンプル
まず、今回の実装の元にした公式サンプルを紹介します。
上で掲載していた p5.tween のリポジトリのページ上部には、1つのボールがバウンドするアニメーションが掲載されています。
その実装は、以下の公式サンプル 6つの中に含まれています。
●p5.js Web Editor | p5.tween
https://editor.p5js.org/Milchreis/collections/oHxcCR17k
具体的には、以下の「bounce」です。
●p5.js Web Editor | bounce
https://editor.p5js.org/Milchreis/sketches/Ypr3RYWfL
実装は以下の通りで、わりとシンプルなつくりになっていると思います。
(addMotions() がいくつか連なるところは、長くなってしまってますが)
const myShape = {
x: 200,
y: 100,
w: 50,
h: 50
}
function setup() {
createCanvas(400, 400);
rectMode(CENTER)
p5.tween.manager.addTween(myShape, 'tween1')
.addMotions([
{ key: 'y', target: height },
{ key: 'w', target: 30 },
{ key: 'h', target: 80 },
], 600, 'easeInQuad')
.addMotions([
{ key: 'w', target: 100 },
{ key: 'h', target: 10 },
], 120)
.addMotions([
{ key: 'w', target: 10 },
{ key: 'h', target: 100 },
], 100)
.addMotions([
{ key: 'w', target: 50 },
{ key: 'h', target: 50 },
{ key: 'y', target: 100 }
], 500, 'easeOutQuad')
.startLoop()
}
function draw() {
background(220);
noStroke()
fill(255, 0, 0)
ellipse(myShape.x, myShape.y, myShape.w, myShape.h)
}
function mousePressed() {
let tween = p5.tween.manager.getTween('tween1')
if(tween.isPaused) tween.resume()
else tween.pause()
}
myShape で、円の位置・大きさの初期値を決め、それを時間変化させる設定を p5.tween.manager.addTween(myShape, 'tween1')
の後につなげている形です。
途中、「easeInQuad」「easeOutQuad」といったイージングを適用した部分もあります。
これにより、緩急のついた動きになっていると思います。
上記のサンプルに手を加えてみる
上記のサンプルに手を加えてみます。
実装内容は、以下の通りです。
let myShapeList = [];
const ballNum = 6;
function setup() {
createCanvas(550, 400);
colorMode(HSB, 360, 100, 100, 100);
initializeShapes();
setupAnimations();
}
function initializeShapes() {
for (let i = 1; i <= ballNum; i++) {
const x = width * (i / (ballNum + 1));
const y = height * random(0.2, 0.5);
const wh = height * random(0.05, 0.15);
myShapeList.push({
x: x,
y: y,
w: wh,
h: wh,
initialX: x,
initialY: y,
initialW: wh,
initialH: wh,
colorH: random(360),
});
}
}
function setupAnimations() {
for (const shape of myShapeList) {
p5.tween.manager
.addTween(shape, "tween1")
.addMotions(
[
{ key: "y", target: height },
{ key: "w", target: shape.initialW * 0.6 },
{ key: "h", target: shape.initialH * 1.6 },
],
600,
"easeInQuad"
)
.addMotions(
[
{ key: "w", target: shape.initialW * 2 },
{ key: "h", target: shape.initialH * 0.2 },
],
120
)
.addMotions(
[
{ key: "w", target: shape.initialW * 0.2 },
{ key: "h", target: shape.initialH * 2 },
],
100
)
.addMotions(
[
{ key: "w", target: shape.initialW },
{ key: "h", target: shape.initialH },
{ key: "y", target: shape.initialY },
],
500,
"easeOutQuad"
)
.startLoop();
}
}
function draw() {
background(10);
noStroke();
for (const s of myShapeList) {
fill(s.colorH, 60, 90);
ellipse(s.x, s.y, s.w, s.h);
}
}
変更を加えた箇所は、円を複数にする部分と、それらの複数の円の初期パラメータをランダムにばらけさせる処理を入れているところです。
この実装をした結果、冒頭のアニメーションができあがりました。
余談: 自分が気になる公式サンプル
上で、公式サンプルが複数あるということを書いていました。
その中で、バウンドするボール以外に、自分が個人的に気になるもののリンクを紹介しておきます。
時計
1つは、数字がアニメーションして変わる時計です。
●p5.js Web Editor | Clock
https://editor.p5js.org/Milchreis/sketches/euDDMbdjP
画像だと分からないですが、数字が切り替わるときにアニメーションが適用されています。
マウスを追いかける残像付で動く円
次は、マウスを追いかける残像付で動く円のアニメーションです。
●p5.js Web Editor | Mouse follow
https://editor.p5js.org/Milchreis/sketches/PIyxxZupt
画面の中で、マウスカーソルを適用に動かしているだけで、ちょっと楽しくなる感じのものです。