围绕圆圈旋转一条线

时间:2015-12-24 10:15:39

标签: javascript animation math canvas geometry

我有两个带笔画的弧线,我希望它们之间有一条线条动画。该线应该垂直于内圈的点动画。

这是我一起入侵的东西,几乎是我想要的东西。

错误的是:

  • 线条的长度不是围绕内圈旋转的2圈之间的长度。
  • 有时线条不垂直于内圈的点。例如,当它到达圆角时,它会倾斜一点角度。

我在理解如何使用lineTo的trig函数时遇到了问题。也许是因为这改变了线的长度,我不知道如何获得外圆的x和y坐标以获得线的终点。我曾经常常做math.cos * length,这给了我一个角度的线。我不知道我只想要外圈的坐标。



window.onload = function(){
	var canvas = document.getElementById("canvas");
	var context = canvas.getContext("2d");
	function lineAtAngle(startX, startY, angleDeg, length, startX2, startY2, angleDeg2, length2){
			var angle = angleDeg * (Math.PI / 180);
			var angle2 = angleDeg2 * (Math.PI / 180);
			// context.moveTo(startX, startY);
			context.beginPath();
			context.moveTo(
				Math.cos(angle) * length + startX,
				Math.sin(angle) * length + startY
				)
			 context.lineTo(
				Math.cos(angle2) *(length2 )+ startX2,
				Math.sin(angle2)  *(length2) + startY2
				)
			// context.lineTo(canvas.width / 2 + 60, canvas.height / 2, angle2, length2)
			
			context.lineWidth = 10;
			context.stroke();
			context.closePath();
			console.log("startX2: " + startX2 + " startY2: " + startY2 )
			console.log(Math.sin(angle2) + startY2)
			console.log(length)
	}
	function myLineTo(startX, startY, angleDeg, length){

	}
	var length1 = canvas.width / 2 + 60 - canvas.width / 2 -30
	var length2 = canvas.width / 2 ;
	// var length2 = 1;
	console.log(length2)
	var angle1 = 0;
	var angle2 = 0;
	(function animate(){
		context.clearRect(0,0, canvas.width, canvas.height);
		window.requestAnimationFrame(animate);	
		context.beginPath()
		context.arc(canvas.width / 2, canvas.height / 2, 30, 0, 2 * Math.PI, true)
		context.lineWidth = 1;
		context.stroke()

		context.beginPath();
		context.arc(canvas.width / 2, canvas.height / 2, 60, 0, 2 * Math.PI, true);
		context.stroke();
		context.closePath()

		context.beginPath();
		context.arc(canvas.width / 2, canvas.height / 2, 3, 0, 2 * Math.PI, true)
		context.fill()
		context.closePath();
		angle1++
		angle2++
		// lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, length1, canvas.width / 2 + 60, canvas.height / 2, angle2, length2 )
		lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, length1, canvas.width / 2 + 60, canvas.height / 2, angle2, length2 )




	}())

}

		canvas{
			background: #aaa;
		}

<canvas id="canvas" width="400" height="400"></canvas>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

我相信以下是你想要实现的目标。

我通过使用Canvas的内置方法将坐标空间转换为中心并通过删除额外的函数来简化代码,这些函数在需要的时候只需要一个角度和两个半径就会传递太多参数。

window.onload = function(){
	var canvas = document.getElementById("canvas");
	var context = canvas.getContext("2d");

	var radius1 = 30;
	var radius2 = 60;
	var angle = 0;

	(function animate(){
		context.clearRect(0, 0, canvas.width, canvas.height);

		// save state and adjust coordinate space
		context.save();
		context.translate(canvas.width / 2, canvas.height / 2);

		context.lineWidth = 1;

		context.beginPath()
		context.arc(0, 0, radius1, 0, 2 * Math.PI, true)
		context.stroke()

		context.beginPath();
		context.arc(0, 0, radius2, 0, 2 * Math.PI, true);
		context.stroke();

		context.beginPath();
		context.arc(0, 0, 3, 0, 2 * Math.PI, true);
		context.fill()

		++angle;
		var rads = angle * Math.PI / 180;
		var x = Math.cos(rads);
		var y = Math.sin(rads);

		context.lineWidth = 10;
		context.beginPath();
		context.moveTo(radius1 * x, radius1 * y);
		context.lineTo(radius2 * x, radius2 * y);
		context.stroke();

		// restore transformations for next pass
		context.restore();

		window.requestAnimationFrame(animate)
	}())

}
canvas { background: #aaa; }
<canvas id="canvas" width="400" height="200"></canvas>

答案 1 :(得分:0)

绘制线条的想法是,您需要提供一个起点(moveTo)和一个终点(lineTo)。您当前的代码使整个事物的角度和长度变得复杂。您想要做的是从圆的中心开始,然后添加一个偏移点,将起点放在内圆的边缘。在这里使用trig非常好。线的长度将只是外半径减去内半径,与偏移方向相同(只需要一个角度)。

如果不从根本上改变您的方法,下面的代码会显示您可以用来尝试此操作的更改。让line函数取一个起点(x,y)和一个偏移量,以及角度和长度。起点是圆心,偏移是内圆的半径。长度(再次)只是外半径减去内半径。

&#13;
&#13;
window.onload = function(){
   var innerCircleRadius = 30;
   var outerCircleRadius = 60;
   var canvas = document.getElementById("canvas");
   var context = canvas.getContext("2d");
   var angle1 = 0;
   function lineAtAngle(startX, startY, angleDeg, offset, length) {
      var angle = angleDeg * (Math.PI / 180); // Convert to radians.
      var cosAngle = Math.cos(angle); // Only need cos(angle) once.
      var sinAngle = Math.sin(angle); // Only need sin(angle) once.
      var startXPos = cosAngle * offset + startX; 
      var startYPos = sinAngle * offset + startY; 
      var endXPos = cosAngle * length + startXPos;
      var endYPos = sinAngle * length + startYPos;
      context.beginPath();
            
      context.moveTo(startXPos, startYPos);
      context.lineTo(endXPos, endYPos); 
			
      context.lineWidth = 10;
      context.stroke();
      context.closePath();
   }
   (function animate() {
	  context.clearRect(0,0, canvas.width, canvas.height);
	  window.requestAnimationFrame(animate);	
	  context.beginPath()
	  context.arc(canvas.width / 2, canvas.height / 2, innerCircleRadius, 0, 2 * Math.PI, true)
	  context.lineWidth = 1;
	  context.stroke()

	  context.beginPath();
	  context.arc(canvas.width / 2, canvas.height / 2, outerCircleRadius, 0, 2 * Math.PI, true);
	  context.stroke();
	  context.closePath()

	  context.beginPath();
	  context.arc(canvas.width / 2, canvas.height / 2, 3, 0, 2 * Math.PI, true)
	  context.fill()
	  context.closePath();
	  angle1++
	  lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, innerCircleRadius, outerCircleRadius - innerCircleRadius);
   }())
}
&#13;
canvas {
   background: #aaa;
}
&#13;
<canvas id="canvas" width="400" height="400"></canvas>
&#13;
&#13;
&#13;