【问题标题】:Javascript animation easingJavascript动画缓动
【发布时间】:2015-10-06 14:09:00
【问题描述】:

我有一个功能可以轻松地移动我的画布。问题是画布动画不起作用。它只是滚动得太远,而且似乎也太快了。

这是我的函数,它将相机移动到用户在画布上单击的位置:

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/ 只需单击画布滚动到该位置,您会发现它有点疯狂。

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

【问题讨论】:

  • @Kaiido 当我有不同的设置时,它是它的早期版本。这确实有效,但它曾经将相机位置设置为其位置,因为我想获得差异并更新每个循环的相机偏移量。此外,正如您在 jsFiddle 中看到的那样,自从更改后它实际上并没有工作,我不确定为什么。

标签: javascript animation math canvas easing


【解决方案1】:

我稍微改了一下你的版本,好像可以用了,试试这个:

    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();

【讨论】:

  • 您能解释一下您所做更改的逻辑,以便我了解我哪里出错了
  • 基本上,我应用了 3 件事:1) 修复 camera.x 和 camera.y 的增量,在分数函数中你有“camera.x -= x”(对于 camera.x -= x)也是一样的。 y) 我意识到画布正在消失而不是靠近,这就是为什么我将表达式更改为“camera.x += x”。
  • 2) 当我修复 camera.x 的增量时,我意识到即使达到目标画布也会继续前进,然后我添加了条件以查看“camera.x”之间的差异+ x”和“target.x”大于“camera.x - target.x”,如果是,这意味着如果我分配“camera.x += x”我将通过目标,然后我分配了值目标“camera.x = target.x”(camera.y 相同)
  • 3) 当我到达目标时,是时候更新画布的初始坐标以便允许从当前位置开始继续下一个 clic:“initial.x = target.x” (对于 initial.y 也是如此)。我希望我已经给你一个很好的解释,问候。
  • 对我来说,这只是以闪电般的速度移动盒子,我没有看到需要 800 毫秒的缓动动画..所以我会说它真的不起作用。见这里:jsfiddle.net/mmcfvr9t - 你的答案没有使用t,它被传递给函数fraction
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2011-11-19
  • 2016-06-28
  • 1970-01-01
相关资源
最近更新 更多