我在围绕中心点的圆形“轨道”中以相等的分布排列圆圈,使用以下数学,其中k是其集合中圆圈的索引,n是集合中圆圈的总数,r是距中心点的距离,x和y是中心点本身:
left = x + r * cos(2*k*PI/n)
top = y + r * sin(2*k*PI/n)
我试图通过这种方式进行试验,并试图通过应用旋转角度并使用计时器增加角度来动画来设置这些圆圈的动画。如果我的弧度为弧度,如何修改上述方程以应用所述旋转变换?
答案 0 :(得分:2)
最简单的方法是设置一个新变量,让我们将其称为myRotation
并将其添加到您的角度,这样每个圆圈都会保持相同的弧度。
left = x + r * cos(2*k*PI/n+myRotation)
top = y + r * sin(2*k*PI/n+myRotation)
继续增加myRotation
并重新绘制圆圈。见下面的例子
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
c.width = 500;
c.height = 500;
var x = c.width/2;
var y = c.height/2;
var n = 8; //number of circles
var r = 100; // radius of large circle, along which all small circles travel
var myRotation=0;
function drawCircles() {
ctx.clearRect(0,0,c.width,c.height);
for (var k=0; k<n; k++) {
ctx.beginPath();
ctx.arc(x+r*Math.cos(2*k*Math.PI/n+myRotation),y+r*Math.sin(2*k*Math.PI/n+myRotation),20,0,2*Math.PI);
ctx.stroke();
}
myRotation+=0.005;
requestAnimationFrame(drawCircles);
}
drawCircles();
&#13;
<canvas id="myCanvas"></canvas>
&#13;
答案 1 :(得分:0)
在我的回答中我已经多次说过了这一点,但是请记住,使用Context2D,如果你不想做的话,你就不需要做数学(或者如果你不知道)。
变换(translate
,rotate
,scale
)允许您将画布视为可以移动,旋转,放大/缩小这些功能的纸张,然后你只需要知道在哪里放笔,从那里去哪里,最后填充/描边。
您应该毫不犹豫地构建小型绘图功能来构建您的绘图,促进重复使用,轻松调试和轻松更改。
在你的例子中,我们首先绘制行星。
function drawPlanets(context, centerX, centerY, orbitDistance, planetCount) {
context.save(); // save the context before any transform.
context.translate(centerX, centerY); // move to the center
var angle = 2 * Math.PI / planetCount; // angle between two planets
for (var i = 0; i < planetCount; i++) {
drawPlanet(context, orbitDistance);
context.rotate(angle);
}
context.restore(); // restore to previous state
}
// draw a planet in the current context, that is centered
// and already oriented towards the planet.
function drawPlanet(context, distance) {
drawCircle(context, distance, 0, planetsRadius);
}
function drawCircle(context, x, y, radius, fill) {
context.fillStyle = fill || '#ADB';
context.beginPath();
context.arc(x, 0, radius, 0, 2 * Math.PI);
context.fill();
}
var sunRadius = 80;
var planetsOrbit = 160;
var planetsRadius = 20;
var planetCount = 8;
var sunPosition = {
x: 200,
y: 200
};
// boilerPlate
var context = cv.getContext('2d');
drawPlanets(context, sunPosition.x, sunPosition.y, planetsOrbit, planetCount);
<canvas id='cv' width=400 height=400></canvas>
现在要建立一个动画,你只需要在绘制行星之前旋转整个上下文,然后再增加一点:
function drawPlanets(context, centerX, centerY, orbitDistance, planetCount, angleShift) {
context.save(); // save the context before any transform.
context.translate(centerX, centerY); // move to the center
// !!!! Only change is here !!!!
context.rotate(angleShift || 0 );
var angle = 2 * Math.PI / planetCount; // angle between two planets
for (var i = 0; i < planetCount; i++) {
drawPlanet(context, orbitDistance);
context.rotate(angle);
}
context.restore(); // restore to previous state
}
// draw a planet in the current context, that is centered
// and already oriented towards the planet.
function drawPlanet(context, distance) {
drawCircle(context, distance, 0, planetsRadius);
}
function drawCircle(context, x, y, radius, fill) {
context.fillStyle = fill || '#ADB';
context.beginPath();
context.arc(x, 0, radius, 0, 2 * Math.PI);
context.fill();
}
function drawScene() {
context.clearRect(0, 0, cv.width, cv.height);
drawPlanets(context, sunPosition.x, sunPosition.y, planetsOrbit, planetCount, (Date.now() - startTime ) / 1000);
}
var sunRadius = 80;
var planetsOrbit = 160;
var planetsRadius = 20;
var planetCount = 8;
var sunPosition = {
x: 200,
y: 200
};
// boilerPlate
var context = cv.getContext('2d');
var startTime = Date.now();
setInterval( drawScene, 30);
<canvas id='cv' width=400 height=400></canvas>