【问题标题】:How can I rotate these offsets by an angle?如何将这些偏移旋转一个角度?
【发布时间】:2015-10-29 06:46:12
【问题描述】:

我正在围绕中心点的圆形“轨道”中以均匀分布的方式排列圆圈,其中 k 是圆圈在其集合中的索引,n 是圆圈中的总数,r是到中心点的距离,x 和 y 是中心点本身:

left = x + r * cos(2*k*PI/n)
top = y + r * sin(2*k*PI/n)

我在尝试通过这种方式进行尝试和错误,现在我正在尝试通过应用旋转角度并使用计时器增加角度来为这些圆圈设置动画以进行动画处理。如果我的角度是弧度,如何修改上述方程以应用所述旋转变换

【问题讨论】:

  • 你能把它放在一个工作小提琴上

标签: canvas d3.js html5-canvas 2d processing


【解决方案1】:

最简单的方法是设置一个新变量,我们将其命名为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();
&lt;canvas id="myCanvas"&gt;&lt;/canvas&gt;

【讨论】:

    【解决方案2】:

    我在回答中已经说过几次了,但请始终记住,使用 Context2D,如果您不想(或者如果您不想不知道)。

    变换(translaterotatescale)允许您将画布视为一张纸,您可以使用这些功能移动、旋转、放大/缩小,然后您就不得不想把你的笔放在哪里,从那里去哪里,最后填充/描边。

    您应该毫不犹豫地构建小型绘图函数来构建您的绘图,以促进重用、易于调试和轻松更改。

    在你的例子中,我们先画行星。

    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);
    &lt;canvas id='cv' width=400 height=400&gt;&lt;/canvas&gt;

    现在要构建一个动画,你只需要在绘制行星之前旋转整个上下文,就是这样:

    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);
    &lt;canvas id='cv' width=400 height=400&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多