context.moveTo()x和y参数不使用requestAnimationFrame递减

时间:2015-12-17 04:08:47

标签: javascript canvas trigonometry

我有两条90度角的线,我希望通过旋转垂直线使角度在90和0之间变小。我正在尝试这样做我更改moveTo参数我可以增加值但不减少它们。你也可以帮我确保在动画过程中移动的线与水平线的长度相同。现在它看起来变得越来越小,然后在完成时变大。

window.onload = function(){
	var canvas =document.getElementById("canvas");
	var context = canvas.getContext("2d");
	var length = 50;
	var x = 50;
	var y= 50;
	var forward = true;

	
	(function animate(){
		if(x  <= 201 && y <= 201){
			x++
			y++
			
		}
		if(x  > 195){
			forward = false;
		}
		// console.log(x, y)
		 if(forward == false){
		 	// alert("yo")
			x = x - 1
			y = y -1
		}
		console.log(x)
		console.log(forward)
		context.clearRect(0,0, canvas.width, canvas.height)
		context.beginPath();
		context.moveTo(x,y)
		context.lineTo(50,200);
		context.stroke();
		context.closePath();
		window.requestAnimationFrame(animate)
		

		context.beginPath();
		context.moveTo(50, 200);
		context.lineTo(200, 200)
		context.stroke();
		context.closePath();

	}())
   }
<canvas id="canvas" width="400" height="400"></canvas>

EDIT :::

window.onload = function(){
	var canvas =document.getElementById("canvas");
	var context = canvas.getContext("2d");
	var length = 50;
	var x = 50;
	var y= 50;
	var dlt  = 1
	var forward = true;
	var i = 0;

	
	(function animate(){
		if(x >= 50 && x < 200 ){
			i++

			x += dlt
			y += dlt
			console.log(i)
			$(".display").html(i)
			if(i >= 150){
				X = 200;
				Y = 200;
				x -= dlt
				y -= dlt
			}
			
		}

		console.log("x", x)
		console.log(forward)
		context.clearRect(0,0, canvas.width, canvas.height)
		context.beginPath();
		context.moveTo(x,y)
		context.lineTo(50,200);
		context.stroke();
		context.closePath();
		window.requestAnimationFrame(animate)
		

		context.beginPath();
		context.moveTo(50, 200);
		context.lineTo(200, 200)
		context.stroke();
		context.closePath();

	}())

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="400" height="400"></canvas>

2 个答案:

答案 0 :(得分:2)

您可以使用变换而不是三角函数来绘制垂直折叠线:

这是带注释的代码和演示:

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

var nextTime=0;
var delay=100;
var angle=-Math.PI/2;
var cx=150;
var cy=150;
var radius=50;

requestAnimationFrame(animate);

function animate(time){

  // wait until the desired time elapses
  if(time<nextTime){requestAnimationFrame(animate); return;}
  nextTime+=delay;

  // draw the horizontal line
  ctx.clearRect(0,0,cw,ch);
  ctx.beginPath();
  ctx.moveTo(cx,cy);
  ctx.lineTo(cx+radius,cy);
  ctx.stroke();

  // use transformations to draw the vertical line
  // at the desired angle
  ctx.translate(cx,cy);
  ctx.rotate(angle);
  ctx.beginPath();
  ctx.moveTo(0,0);
  ctx.lineTo(radius,0);
  ctx.stroke();
  ctx.setTransform(1,0,0,1,0,0);

  // if the vertical line isn't horizontal, 
  // request another animation frame
  if(angle<0){ requestAnimationFrame(animate); }

  // adjust the angle
  angle+=Math.PI/90;
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

如果您想使用Trig,那么您可以像这样计算线端点:

var lineX1 = lineX0 + radius*Math.cos(angle);
var lineY1 = lineY1 + radius*Math.sin(angle);

[另外:在提问者的代码中添加三角法]

以下是重构的代码,使用三角函数重新定位垂直线。

var canvas =document.getElementById("canvas");
var context = canvas.getContext("2d");
var length = 50;
var x = 50;
var y= 50;
var dlt  = 1
var forward = true;
var i = 0;

var angle=-Math.PI/2;
var direction=1;

(function animate(){

  /*
		if(x >= 50 && x < 200 ){
			i++

			x += dlt
			y += dlt
			console.log(i)
			$(".display").html(i)
			if(i >= 150){
				X = 200;
				Y = 200;
				x -= dlt
				y -= dlt
			}

		}
*/

  var moveX=50+(200-50)*Math.cos(angle);
  var moveY=200+(200-50)*Math.sin(angle);

  // change the angle
  angle+=(Math.PI/120*direction);

  // if the angle is beyond vertical or horizontal then
  // swing it the other way
  if(angle<-Math.PI/2 || angle>0){ direction*=-1;}

  context.clearRect(0,0, canvas.width, canvas.height)
  context.beginPath();
  context.moveTo(moveX,moveY)
  context.lineTo(50,200);
  context.stroke();
  //		context.closePath();

  context.beginPath();
  context.moveTo(50, 200);
  context.lineTo(200, 200)
  context.stroke();
  //		context.closePath();

  window.requestAnimationFrame(animate)

}())
<canvas id="canvas" width=300 height=300></canvas>

答案 1 :(得分:1)

Sin and Cos

所有图形程序员都应该彻底了解这两个三角函数。

MarkE 给出了一个很好的答案,但我会指出一个简单的trig方法,你可以用它来找到一个所需距离和角度的点。

让我们说你想要的行有一个长度,

var length = 100;

开始于,

var posX = 200;
var posY = 200;

未知的结束位置将是,

var endX;
var endY;

和你想要的角度是

var angle = 0; // in radians 

Radians V Degrees 在javascript中,所有需要角度的数学函数都使用角度作为弧度。 以上angle为弧度,angle = 0在屏幕上从左到右指向,angle = Math.PI/2(90度)从屏幕上方向上,angle = Math.PI(180度)从右侧离开屏幕并angle = Math.PI * (3/2)(270度)从屏幕的底部到顶部。

如果你想以度数工作,那么你可以通过将度数乘以Math.PI/180.

来转换为弧度

将度数转换为弧度的功能

function degree2Radians(deg){
    return deg * (Math.PI/180);
}

回到以某个角度获取线条。我们将使用trig函数Math.cosMath.sin查看Wiki trigonometric functions以获取详细信息。

所以按步骤计算

var x,y; // temp working variables
x = Math.cos(angle);  // get the amount of x in the line for angle
y = Math.sin(angle);  // get the amount of y in the line for angle 
// cos and sin will return values -1 to 1 inclusive.

// now scale the values to the length of the line
x *= length;
y *= length;

// now you have the offset from the start of the line
// to get the end point add the start
endX = x + posX;
endY = y + posY;

现在你可以按照你想要的角度绘制线条。

ctx.beginPath();
ctx.moveTo(posX,posY);
ctx.lineTo(endX,endY);
ctx.stroke();

当然,这还有很长的路要走。这一切都可以分两步完成。

endX = Math.cos(angle) * length + posX;
endY = Math.sin(angle) * length + posY;

或者如果您喜欢以度为单位的函数

// add to the current path a line from 
// startX,startY of 
// length pixels long
// at the angle angleDeg in degrees. Negative anticlockwise positive clockwise
function lineAtAngle(ctx, startX, startY, angleDeg, length){
    var angle = angleDeg * (Math.PI / 180);
    ctx.moveTo(startX, startY);
    ctx.lineTo(
        Math.cos(angle) * length + startX,
        Math.sin(angle) * length + startY
    )
}

并使用它

ctx.beginPath(); // begin the line
lineAtAngle(ctx,200,200,-45,100); // draw a line at -45deg 
                                  // (from bottom left to top right)
                                  // 100 pixels long.
ctx.stroke();  // draw the line  

这是如何使用sin和cos以一个角度和长度画一条线。