WEBOPIXEL

HTML5+Canvasで学ぶインタラクティブアニメーションの基礎

Posted: 2015.08.27 / Category: javascript / Tag: ,

すごく簡単なものですが、HTML5+Canvasを使用してマウスの操作に反応するインタラクティブアニメーションを作成してみたいと思います。

Sponsored Link

Canvasアニメーションの基礎については下記を参考にしてください。
この記事は下記をベースとして進めます。

HTML5で作るCanvasアニメーションの基礎
HTML5+Canvasでパーティクルっぽいのを作ってみる
HTML5+Canvasで学ぶ物理アニメーションの基礎

マウスのイベントの取得方法

JavaScriptでクリックイベントを取得するには「addEventListener」を使用します。
例えばcanvas内でクリックした情報を取得したい場合は下記のようにします。

canvas.addEventListener('click', function(e) {
    console.log('click');
}, false);

「click」を「mousemove」とすればマウス移動時にイベントが実行されます。

canvas.addEventListener('mousemove', function(e) {

マウスの位置を取得する

「e.clientX」「e.clientY」でマウスのX,Y座標を取得できますがそのままだと画面全体の座標になります。
canvas内の座標を取得する場合は「getBoundingClientRect」でcanvasの座標値を引きます。

var rect = canvas.getBoundingClientRect();
canvas.addEventListener('click', function(e) {
    var mouseX = e.clientX - rect.left;
    var mouseY = e.clientY - rect.top;
}, false);

マウスに追従して移動する

イベントの取得方法がわかったところで、適当なオブジェクトをマウスカーソルに追従させてみましょう。以前の記事と組み合わせるとわりと簡単にできます。

See the Pen JYPPje by webopixel (@webopixel) on CodePen.

window.requestAnimFrame = (function(){
    return  window.requestAnimationFrame   ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        window.oRequestAnimationFrame      ||
        window.msRequestAnimationFrame     ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        };
})();

window.onload = function() {
    // Canvas未サポートは実行しない
    if (!window.HTMLCanvasElement) return;
    var canvas = document.querySelector('#canvas-container');
    var ctx = canvas.getContext('2d');
    //マウスをクリックした座標
    var clickPoint = {
        x: 0,
        y: 0
    };

    var Particle = function(scale, color, speed) {
        this.scale = scale; //大きさ
        this.color = color; //色
        this.speed = speed; //速度
        this.position = {   // 位置
            x: 0,
            y: 0
        };
    };

    Particle.prototype.draw = function() {
        ctx.beginPath();
        ctx.arc(this.position.x, this.position.y, this.scale, 0, 2*Math.PI, false);
        ctx.fillStyle = this.color;
        ctx.fill();
    };

    Particle.prototype.update = function() {
        this.position.x += (clickPoint.x - this.position.x) / this.speed;
        this.position.y += (clickPoint.y - this.position.y) / this.speed;

        this.draw();
    };

    var particle = new Particle(7, '#D0A000', 20);

    var loop = function() {
        requestAnimFrame(loop);
        // 描画をクリアー
        ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height);

        particle.update();
    };
    loop();

    var rect = canvas.getBoundingClientRect();

    // マウスカーソルを動かしたら実行する
    canvas.addEventListener('mousemove', function(e) {
        var mouseX = e.clientX - rect.left;
        var mouseY = e.clientY - rect.top;

        clickPoint.x = mouseX;
        clickPoint.y = mouseY;

    }, false);
};