2014-10-27 69 views
0

我正在嘗試使球在線上移動,同時旋轉與緩動 ..我的問題是,在旋轉線的同時,Y軸球被改變。在Y軸上旋轉HTML5畫布中的JS對象時出現的問題

注意旋轉整個畫布旋轉線的時候,但我不知道如何解決它

也許在我的代碼。

演示 http://jsfiddle.net/mgazzar/o487tnb5/38/

這裏是線的繪製

ctx.save(); 
ctx.translate(canvas.width/2,canvas.height/2); 
ctx.rotate(angle * Math.PI/180) ; 
ctx.beginPath(); 
ctx.moveTo(-lineLength/2,0); 
ctx.lineTo(lineLength/2,0); 
ctx.lineWidth=5; 
ctx.strokeStyle='white'; 
ctx.fillStlye = "white"; 
    ctx.stroke(); 
ctx.restore(); 

回答

0

你行代碼是正確的,問題是你如何渲染球。在線條繪製中,您在ctx.rotate之前正確運行ctx.translate(canvas.width/2,canvas.height/2),以便線條圍繞畫布中心旋轉。然而,你在ball2.draw中不做任何類似的操作,所以球在畫布左上角的畫布上旋轉0,0。

在旋轉畫布(下圖1)之前,您可以通過執行相應的ctx.translate來解決此問題。但是,在旋轉之後,你還需要小心地做相反的翻譯(2)。如果不是,根據需要,您的球將使用this.x,this.y相對於畫布的中心繪製,而不是相對於(旋轉的)屏幕的左上角。

// Function for drawing ball on canvas 
draw: function() { 
    ctx.save(); 
    ctx.beginPath(); 
    ctx.translate(canvas.width/2,canvas.height/2);  // 1 
    ctx.rotate(angle * Math.PI/180) ; 
    ctx.translate(-canvas.width/2,-canvas.height/2); // 2 
    ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, false); 
    ctx.fillStyle = "white"; 
    ctx.fill(); 
    ctx.restore(); 

    } 
+0

謝謝你,它現在是我清楚。 – john 2014-10-27 20:55:32

1

您還可以使用羅伯特Penners著名寬鬆方程與一個寬鬆的效果旋轉你的對象:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 

 
var easingType='easeOutBounce'; 
 
var PI=Math.PI; 
 
var x=60; 
 
var y=100; 
 
var circumference; 
 
var minAngle=0; 
 
var maxAngle=PI*4; 
 
var currentT=0; 
 
var maxT=100; 
 

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/ball1.png"; 
 
function start(){ 
 
    circumference=PI*img.width; 
 
    drawBall(x,y,0); 
 
    animate(); 
 
} 
 

 

 
function animate(){ 
 
    if(currentT<maxT){requestAnimationFrame(animate);} 
 

 
    var easedAngle=Easings[easingType](currentT,minAngle,maxAngle,maxT); 
 
    var easedX=x+easedAngle/maxAngle*circumference*2; 
 
    drawBall(easedX,y,easedAngle); 
 

 
    currentT+=1; 
 
} 
 

 
function drawBall(x,y,rAngle){ 
 
    ctx.clearRect(0,0,cw,ch); 
 
    ctx.fillRect(0,y,cw,1); 
 
    ctx.save(); 
 
    ctx.translate(x,y); 
 
    ctx.rotate(rAngle); 
 
    ctx.drawImage(img,-img.width/2,-img.height/2); 
 
    ctx.restore(); 
 
} 
 

 
// Robert Penner's easing algorithms 
 
// t: current time, 
 
// b: begInnIng value, 
 
// c: change In value, 
 
// d: duration 
 
Easings={ 
 

 
    easeLinear: function(t, b, c, d){ 
 

 
    }, 
 

 
    swing: function (t, b, c, d) { 
 
    return jQuery.easing[jQuery.easing.def](t, b, c, d); 
 
    }, 
 
    easeInQuad: function (t, b, c, d) { 
 
    return c*(t/=d)*t + b; 
 
    }, 
 
    easeOutQuad: function (t, b, c, d) { 
 
    return -c *(t/=d)*(t-2) + b; 
 
    }, 
 
    easeInOutQuad: function (t, b, c, d) { 
 
    if ((t/=d/2) < 1) return c/2*t*t + b; 
 
    return -c/2 * ((--t)*(t-2) - 1) + b; 
 
    }, 
 
    easeInCubic: function (t, b, c, d) { 
 
    return c*(t/=d)*t*t + b; 
 
    }, 
 
    easeOutCubic: function (t, b, c, d) { 
 
    return c*((t=t/d-1)*t*t + 1) + b; 
 
    }, 
 
    easeInOutCubic: function (t, b, c, d) { 
 
    if ((t/=d/2) < 1) return c/2*t*t*t + b; 
 
    return c/2*((t-=2)*t*t + 2) + b; 
 
    }, 
 
    easeInQuart: function (t, b, c, d) { 
 
    return c*(t/=d)*t*t*t + b; 
 
    }, 
 
    easeOutQuart: function (t, b, c, d) { 
 
    return -c * ((t=t/d-1)*t*t*t - 1) + b; 
 
    }, 
 
    easeInOutQuart: function (t, b, c, d) { 
 
    if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 
 
    return -c/2 * ((t-=2)*t*t*t - 2) + b; 
 
    }, 
 
    easeInQuint: function (t, b, c, d) { 
 
    return c*(t/=d)*t*t*t*t + b; 
 
    }, 
 
    easeOutQuint: function (t, b, c, d) { 
 
    return c*((t=t/d-1)*t*t*t*t + 1) + b; 
 
    }, 
 
    easeInOutQuint: function (t, b, c, d) { 
 
    if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 
 
    return c/2*((t-=2)*t*t*t*t + 2) + b; 
 
    }, 
 
    easeInSine: function (t, b, c, d) { 
 
    return -c * Math.cos(t/d * (Math.PI/2)) + c + b; 
 
    }, 
 
    easeOutSine: function (t, b, c, d) { 
 
    return c * Math.sin(t/d * (Math.PI/2)) + b; 
 
    }, 
 
    easeInOutSine: function (t, b, c, d) { 
 
    return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; 
 
    }, 
 
    easeInExpo: function (t, b, c, d) { 
 
    return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; 
 
    }, 
 
    easeOutExpo: function (t, b, c, d) { 
 
    return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; 
 
    }, 
 
    easeInOutExpo: function (t, b, c, d) { 
 
    if (t==0) return b; 
 
    if (t==d) return b+c; 
 
    if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; 
 
    return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; 
 
    }, 
 
    easeInCirc: function (t, b, c, d) { 
 
    return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; 
 
    }, 
 
    easeOutCirc: function (t, b, c, d) { 
 
    return c * Math.sqrt(1 - (t=t/d-1)*t) + b; 
 
    }, 
 
    easeInOutCirc: function (t, b, c, d) { 
 
    if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 
 
    return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 
 
    }, 
 
    easeInElastic: function (t, b, c, d) { 
 
    var s=1.70158;var p=0;var a=c; 
 
    if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 
 
    if (a < Math.abs(c)) { a=c; var s=p/4; } 
 
    else var s = p/(2*Math.PI) * Math.asin (c/a); 
 
    return -(a*Math.pow(2,10*(t-=1)) * Math.sin((t*d-s)*(2*Math.PI)/p)) + b; 
 
    }, 
 
    easeOutElastic: function (t, b, c, d) { 
 
    var s=1.70158;var p=0;var a=c; 
 
    if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 
 
    if (a < Math.abs(c)) { a=c; var s=p/4; } 
 
    else var s = p/(2*Math.PI) * Math.asin (c/a); 
 
    return a*Math.pow(2,-10*t) * Math.sin((t*d-s)*(2*Math.PI)/p) + c + b; 
 
    }, 
 
    easeInOutElastic: function (t, b, c, d) { 
 
    var s=1.70158;var p=0;var a=c; 
 
    if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); 
 
    if (a < Math.abs(c)) { a=c; var s=p/4; } 
 
    else var s = p/(2*Math.PI) * Math.asin (c/a); 
 
    if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin((t*d-s)*(2*Math.PI)/p)) + b; 
 
    return a*Math.pow(2,-10*(t-=1)) * Math.sin((t*d-s)*(2*Math.PI)/p)*.5 + c + b; 
 
    }, 
 
    easeInBack: function (t, b, c, d, s) { 
 
    if (s == undefined) s = 1.70158; 
 
    return c*(t/=d)*t*((s+1)*t - s) + b; 
 
    }, 
 
    easeOutBack: function (t, b, c, d, s) { 
 
    if (s == undefined) s = 1.70158; 
 
    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 
 
    }, 
 
    easeInOutBack: function (t, b, c, d, s) { 
 
    if (s == undefined) s = 1.70158; 
 
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; 
 
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; 
 
    }, 
 
    easeInBounce: function (t, b, c, d) { 
 
    return c - jQuery.easing.easeOutBounce (d-t, 0, c, d) + b; 
 
    }, 
 
    easeOutBounce: function (t, b, c, d) { 
 
    if ((t/=d) < (1/2.75)) { 
 
     return c*(7.5625*t*t) + b; 
 
    } else if (t < (2/2.75)) { 
 
     return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; 
 
    } else if (t < (2.5/2.75)) { 
 
     return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; 
 
    } else { 
 
     return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; 
 
    } 
 
    }, 
 
    easeInOutBounce: function (t, b, c, d) { 
 
    if (t < d/2) return jQuery.easing.easeInBounce (t*2, 0, c, d) * .5 + b; 
 
    return jQuery.easing.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b; 
 
    } 
 
};
body{ background-color: ivory; padding:10px; } 
 
#canvas{border:1px solid red;}
<p>Moving and Rotating with 'InQuad' easing</p> 
 
<canvas id="canvas" width=550 height=200></canvas><br>

+0

謝謝,但是如果有純JS的簡單緩動工具? – john 2014-10-27 21:41:38

+1

相關代碼全是純javascript - 我只是習慣用jQuery來處理再次按鈕點擊。我已經將jQuery從我的演示中拉出來,現在它是純粹的javascript。祝你的項目好運! – markE 2014-10-27 21:45:51