Javascript动画缓和

时间:2015-10-06 05:12:38

标签: javascript animation math canvas easing

我有一个功能,可以轻松地移动我的画布。问题是帆布动画无法发挥作用。它只是滚动得太远而且看起来也太快了。

这是我的功能,可以将相机移动到用户在画布上点击的位置:

function moveCamera(e,parent){
    clearInterval(parent.scroll);

var mouseData       = mousePos(evt,parent); //get x:y relative to element           
var initial         = {'x':el.width/2,'y':el.height/2},
    target          = {'x':mouseData.x,'y':mouseData.y},            
    deltaX          = target.x-initial.x,
    deltaY          = target.y-initial.y,
    timeStart       = Date.now(),
    timeLength      = 800,
    x,y,deltaTime;

function update(){
    function fraction(t){
        x               = (target.x - initial.x) - (t*deltaX),
        y               = (target.y - initial.y) - (t*deltaY);
        camera.x       -= x;
        camera.y       -= y;
    }
    function easing(x) {
        return 0.5 + 0.5 * Math.sin((x - 0.5) * Math.PI);
    }   

    deltaTime = (Date.now() - timeStart) / timeLength;
    if (deltaTime > 1) {
        fraction(1);
    } else {
        fraction(easing(deltaTime));
    }   
}
parent.scroll = setInterval(update, 10);        
}

我已经证实了这个问题的JSFiddle: http://jsfiddle.net/p5xjmLay/ 只需点击画布滚动到那个位置,你会发现它有点疯狂。

我想知道如何解决这个问题,以便每次都能正确改变相机偏移量?

1 个答案:

答案 0 :(得分:0)

我改变了你的版本,似乎它正在运行,请试试这个:

    var el      = document.getElementById('canvas'),
    initial         = {'x':el.width/2,'y':el.height/2},
    ctx     = el.getContext('2d'),
    camera  = {'x':el.width/2,'y':el.height/2},
    box     = {'x':0,'y':0};
    var x,y,deltaTime;

    el.addEventListener('mousedown',function(e){moveCamera(e,this);},false);

function moveCamera(e,parent){
        clearInterval(parent.scroll);

    var mouseData       = mousePos(e,parent);                       
        target          = {'x':mouseData.x,'y':mouseData.y},            
        deltaX          = target.x-initial.x,
        deltaY          = target.y-initial.y,
        timeStart       = Date.now(),
        timeLength      = 800;


    function update(){
        function fraction(t){
            x               = target.x - (initial.x + (t*deltaX)),
            y               = target.y - (initial.y + (t*deltaY));

            if (Math.abs(camera.x + x - target.x) > Math.abs(camera.x - target.x)) {
                camera.x = target.x;
                initial.x = target.x;
            } else {
                camera.x       += x;                
            }

            if (Math.abs(camera.y + y - target.y) > Math.abs(camera.y - target.y)) {
                camera.y = target.y;
                initial.y = target.y;
            } else {
                camera.y       += y;                
            }            

        }
        function easing(x) {
            return 0.5 + 0.5 * Math.sin((x - 0.5) * Math.PI);
        }   

        deltaTime = (Date.now() - timeStart) / timeLength;
        if (deltaTime > 1) {
            fraction(1);
        } else {
            fraction(easing(deltaTime));
        }
        draw(); 
    }
    parent.scroll = setInterval(update, 200);       
}

function mousePos(evt,el){
        var offsetX = 0,
            offsetY = 0;        
        do{
            offsetX += el.offsetLeft - el.scrollLeft;
            offsetY += el.offsetTop  - el.scrollTop;
        }while(el = el.offsetParent){
            return {'x':evt.pageX - offsetX, 'y':evt.pageY - offsetY}       
        }       
}

function draw(){

    ctx.clearRect(0,0,el.width,el.height);

    ctx.save();
    ctx.translate(camera.x,camera.y);     

    ctx.beginPath();
    ctx.rect(box.x-25, box.y-25,50,50);
    ctx.fillStyle = 'red';
    ctx.fill(); 

    ctx.restore();           
}
draw();