2014-10-27 70 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