如何为跟踪鼠标移动的动画添加惯性?

时间:2015-12-19 19:56:41

标签: javascript canvas pixi.js

我正在尝试使用mouseMove事件围绕原点旋转三角形 我正在使用touchstarttouchmove事件获取触摸起点当前触点,然后我找到了方向角容易使用:

alpha = y2 - y1 / x2 - x1;     // alpha is the tangent of the angle
beta= atan(alpha);      // beta is the angle in radians

然后我在PIXI中旋转元素:

function animTriangle (beta) {

  // initially clear the previous shape
  myTriangle.clear();


  // draw a new shape in new positions
  myTriangle.beginFill(0x000000, 0.1);
  myTriangle.moveTo(origin.x, origin.y);
  myTriangle.lineTo(origin.x - 100, 0);
  myTriangle.lineTo(origin.x + 100, 0);
  myTriangle.lineTo(origin.x, origin.y);
  myTriangle.endFill();
  myTriangle.rotation = beta;

}

我正在使用RequestAnimationFrame循环管理我的画作。

问题是动画不稳定,我需要旋转惯性。怎么能解决这个问题?

2 个答案:

答案 0 :(得分:0)

尝试添加另一个变量betaCumulative,并以小增量调整其值,如下所示:

if(beta < betaCumulative)betaCumulative += .01;
if(beta > betaCumulative)betaCumulative -= .01;
myTriangle.rotation = betaCumulative;

答案 1 :(得分:0)

https://codepen.io/Starglider/pen/LYEELVy/left

let log = function (arg) { console.log(arg); }

let container;
let box;
let debug;
let innertia;

function CursorFollow() {
    log("CursorFollow()");

    let container = document.getElementById("container");
    let box = document.getElementById("box");
    let slider = document.getElementById("range");
    let sliderValue = document.getElementById("range-value");
    let debug = document.getElementById("debug");

    let containerX = 0;
    let containerY = 0;
    let limX = 0;
    let limY = 0;

    let inertia = 0.3;

    let cx = 0; // current
    let cy = 0;
    let tx = 0; // target
    let ty = 0;
    let x = 0; // working value
    let y = 0;

    let firstRun = true;

    function init() {

        inertia = parseFloat(slider.value);

        containerX = window.scrollX + container.getBoundingClientRect().left;
        containerY = window.scrollY + container.getBoundingClientRect().top;
        limX = container.getBoundingClientRect().width - box.getBoundingClientRect().width;
        limY = container.getBoundingClientRect().height - box.getBoundingClientRect().height;

        cx = parseFloat(getComputedStyle(box).left);
        cy = parseFloat(getComputedStyle(box).left);

        slider.addEventListener("change", sliderChangeHandler);
        container.addEventListener("mousemove", mouseMoveHandler);

        update();
    }
    // - - - - - -


    function sliderChangeHandler(e){
        inertia = parseFloat(slider.value);
    }
    // - - - - - -


    function mouseMoveHandler(e) {
        // log(e);
        // problem is offsetX&Y goes to zero when mouse doesnt move!
        tx = e.clientX - containerX;
        ty = e.clientY - containerY;

        if (tx > limX){
            tx = limX;
        }
        if (ty > limY){
            ty = limY;
        }

    }
    // - - - - - -


    function update() {

        // So we dont have to getComputerStlye in update loop
        if (firstRun){
            firstRun = false;
        } else {
            cx = x;
            cy = y;
        }


        // debug.innerHTML = cx;
        x = inertiaTo(cx,tx,inertia);
        y = inertiaTo(cy,ty,inertia);

        box.style.left = x + "px";
        box.style.top = y + "px";

        debug.innerHTML = "x:" + x + " y:" + y;

        sliderValue.innerHTML = "inertia: " + inertia;

        requestAnimationFrame(update);
    }
    // - - - - - -


    function inertiaTo(current,target,amount){
        if (amount==1){
            return target;
        }
        let distToGo = target-current;
        let delta = current + (distToGo * amount);

        if (Math.abs(distToGo) < 0.01){
            distToGo = 0;
            delta = target;
        }

        // debug.innerHTML = distToGo;
        return delta;
    }
    // - - - - - -


    // Constructor simulation
    init();
    // - - - - - -

}





new CursorFollow();
* {
    box-sizing: border-box;
}

#container {
    position: relative;
    width: 300px;
    height: 200px;
    background: #CCCCCC;
}

#box {
    position: absolute;
    left: 0;
    top: 0;
    width: 15px;
    height: 15px;
    background: #CC0000;
}


#range-value {
    width: 300px;
    background: #EEEEEE;
    border: 1px solid #CCCCCC;
    text-align: center;
}

#range {
    width: 300px;
}

#debug {
    background: #EEEEEE;
    border: 1px solid #CCCCCC;
    min-height: 25px;
}
<div id="container">
    <div id="box"></div>
</div>

<div id="range-value">0</div>
<input id="range" type="range" min="0" max="0.6" step="0.01" value="0.2"/>

<div id="debug"></div>