我试图让球在线上移动,同时使用缓动旋转。我的问题是,在旋转线时,球的Y轴会发生变化。
注意
也许在我的代码中旋转线条时整个画布旋转但我不知道如何解决它。
演示 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 :(得分:1)
您还可以使用 Robert 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;
}
};
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<p>Moving and Rotating with 'InQuad' easing</p>
<canvas id="canvas" width=550 height=200></canvas><br>
&#13;
答案 1 :(得分:0)
你的线路代码很好,问题在于你如何渲染球。在线条图中,您可以在ctx.translate(canvas.width/2,canvas.height/2)
之前正确运行ctx.rotate
,以便线条围绕画布的中心旋转。但是你在ball2.draw
中没有做任何类似的事情,所以球在画布上的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();
}