11_2 手作りイージング関数を使ったキャンバスアニメーション

Web Animations APIとは直接は関係しませんが、イージング関数に渡す変数t, b, c, dを手作りし、得た結果を反映させるキャンバスアニメーションを作成します。1秒かけて、青い円が20から400まで移動します。

毎フレーム呼び出されるupdate()関数で、変数xposの値に、イージング関数が返す値を代入します。

// イージング関数に(t, b, c, d)を与え、xposを得る
xpos = easing(elapsedTime, startx, defx, duration);

イージング関数は、http://robertpenner.com/easing/を参考に、いくつか定義します。

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
context.fillStyle = 'rgb(10, 87, 175)';

// アニメーションを実行するかどうか
let isRunning = true;

const startx = 20; // 初めの値
const destx = 400; // 終わりの値
const defx = destx - startx; // 変化量
const duration = 1000; // 長さ

// 開始時間値 日付に1を掛けて数値にする
var start = ((new Date()) * 1);
// 経過時間値
let elapsedTime = 0;

// 円を描く最初の位置
let xpos = startx;
let ypos = canvas.height / 2;

// イージング関数各種
// http://robertpenner.com/easing/
const easing1 = (t, b, c, d) => {
    return c * t / d + b;
}
const easing2 = (t, b, c, d) => {
    t /= d;
    // console.log(t*t)
    return c * t * t + b;
}

const easing3 = (t, b, c, d) => {
    if ((t /= d) < (1 / 2.75)) {
        return c * (7.5625 * t * t) + b;
    }
    else if (t < (2 / 2.75)) {
        return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
    }
    else if (t < (2.5 / 2.75)) {
        return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
    }
    else {
        return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
    }
}

// xposの取得にイージング関数を使用する
const update = () => {
    // 現在の時間値
    const now = ((new Date()) * 1);
    // 経過時間値
    elapsedTime = now - start;
    // 経過時間が長さより大きくなったらアニメーションを止める
    if (elapsedTime >= duration) {
        isRunning = false;
    }
    // イージング関数に(t, b, c, d)を与え、xposを得る
    xpos = easing3(elapsedTime, startx, defx, duration);
}

const render = () => {
    update();
    // キャンバスに円のアニメーションを描く
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.beginPath();
    context.arc(xpos, ypos, 10, 0, Math.PI * 2);
    context.fill();
    // isRunningがtrueの場合に、アニメーションを描く
    if (isRunning) {
        window.requestAnimationFrame(render);
    }
}
render();

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA