17/08/07

canvasとjavascriptで慣性の動きをするパーティクル



 

今回はjavascriptとcanvasを用いて、パーティクルに
慣性を取り入れた動きを実装していきたいと思います。
慣性の動きはスマホのスクロールなどに利用されています。

とりあえず、完成品

See the Pen inertia ball by youya66 (@youya66) on CodePen.0

 

以下は簡単な解説になります

慣性

touch_start(){
    this.p1.x = this.p2.x = this.ideal_point.x = $.mouse.x;
    this.p1.y = this.p2.y = this.ideal_point.y = $.mouse.y;
    this.is_touch = true;
}
touch_move(){
    if(this.is_touch){
        this.p1.x = this.p2.x;
        this.p1.y = this.p2.y;

        this.p2.x = this.ideal_point.x = $.mouse.x;
        this.p2.y = this.ideal_point.y = $.mouse.y;
    }
}
touch_end(){
    let dx = this.p2.x - this.p1.x;
    let dy = this.p2.y - this.p1.y;

    this.vx = dx * 2.5;
    this.vy = dy * 2.5;

    this.flag_inertia.x = true;
    this.flag_inertia.y = true;
    this.is_touch = false;
}
move(){
    if(this.flag_inertia.x){
        if(this.x + this.vx - this.radius >= $.width){
            this.vx *= -1;
        }else if(this.x + this.vx - this.radius <= 0){
            this.vx *= -1;
        }else{
            this.x += this.vx;
        }
        this.vx /= 1.15;
        if(this.vx <= 1 && this.vx >= -1){
            this.ideal_point.x = this.x;
            this.flag_inertia.x = false;
        }
    }
    if(this.flag_inertia.y){
        if(this.y + this.vy - this.radius >= $.height){
            this.vy *= -1;
        }else if(this.y + this.vy - this.radius <= 0){
            this.vy *= -1;
        }else{
            this.y += this.vy;
        }
        this.vy /= 1.15;
        if(this.vy <= 1 && this.vy >= -1){
            this.ideal_point.y = this.y;
            this.flag_inertia.y = false;
        }
    }
    if(!this.flag_inertia.x && !this.flag_inertia.y){
        this.x = this.ideal_point.x;
        this.y = this.ideal_point.y;
    }
}

ここでは、一定の間隔でマウスの距離を記録しておき、
マウスが離された時の座標と、一つ前の座標の差分を利用して、速度を出し、
それを再帰処理で徐々に速度を落としていくことで、慣性のような動きになります。

スマホ対応

const support_touch = "ontouchend" in document;
const TOUCH_START = support_touch ? "touchstart": "mousedown";
const TOUCH_MOVE = support_touch ? 'touchmove' : 'mousemove';
const TOUCH_END = support_touch ? 'touchend' : 'mouseup';

ontouchendがdocumentオブジェクトにあるかどうかで、
touch event系かを用いるか、mouse event系を用いるかを分けています。

クリックまたはタップされたcanvas内の座標を取得

$.canvas = document.querySelector(".canvas");
let x;
let y;
let rect = $.canvas.getBoundingClientRect();
let offset_left = Math.floor(rect.left);
let offset_top = Math.floor(rect.top);

今回はcanvasの位置をcssのleftとtransformプロパティで天地中央になるようにしています。
しかし、transformはoffsetleftではうまく取得できないので、getBoundingClientRectを用いて、
offsetを取得しています。

if(e.pageX || e.pageY){
    x = e.pageX;
    y = e.pageY;
}else{
    x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; 
    y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; 
}
$.mouse.x = x - offset_left;
$.mouse.y = y - offset_top;

次にマウスの正しい位置を取得しています。

 

そしてこれらを用いてcanvas内のクリックされた位置を取得しています。

 

以上です。

スポンサーリンク

メールアドレスが公開されることはありません。

youya66

だらけとびびり、それとちょっぴりのてきとーさ。

コアラになってだらだらしながら愛されたい。