Как настроить несколько вращающихся рисунков на холсте (чистый js)

Я создаю солнечную систему с готовыми планетами и хочу знать, как заставить более одной вращаться вокруг солнца. Я столкнулся с проблемой невозможности вращать 2 сразу. Любые решения? Вот текущий код:

Орбитальная страница: var canvasP = document.getElementById("planetsOrbit"); var ctx2 = canvasP.getContext("2d"); var angle = 6 * Math.PI / 180;

var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2.12;
var radiusNew = (window.innerHeight + window.innerWidth) * 0.15;



function resizeCanvasPOrbit() {
ctx2.clearRect(0, 0, canvasP.width, canvasP.height);
 if (canvasP.width < window.innerWidth) {
   canvasP.width = window.innerWidth * 0.99;
   }' 

  if (canvasP.height < window.innerHeight)
   {
    canvasP.height = window.innerHeight * 0.98;
    }
w = canvasP.width
h = canvasP.height
}


 function draw(x, y) {
    ctx2.clearRect(0, 0, w, h);
    ctx2.save();
   ctx2.beginPath();
   ctx2.beginPath();
   roa(x, y, window.innerHeight * window.innerWidth * 0.00008);
   ctx2.stroke();
   ctx2.restore();
 };

  function keepDrawing() {
     ctx2.clearRect(0, 0, w, h);
     draw(newX, newY);
     setTimeout(keepDrawing, 250);
 }

 window.requestAnimFrame = (function (callback) {
   return window.requestAnimationFrame ||
       window.webkitRequestAnimationFrame ||
       window.mozRequestAnimationFrame ||
       window.oRequestAnimationFrame ||
       window.msRequestAnimationFrame || 
       function (callback) { 
        window.setTimeout(callback, 5000 / 60); 
        };
      })();

 var fps = 60;

 function animate() {
  setTimeout(function () {
    requestAnimationFrame(animate);

    // increase the angle of rotation A.K.A SPEED!
    angle += 1 * Math.PI / 3600;

    //calculate the new ball.x / ball.y
    var newX = cx - radiusNew * Math.cos(angle);
       var newY = cy + radiusNew * Math.sin(angle);

       //draw
      ctx2.clearRect(0, 0, w, h);
      draw(newX, newY);

       //draw the centerpoint 
      ctx2.beginPath();
      ctx2.arc(cx, cy, radiusNew, 0, Math.PI * 2, false);
      ctx2.closePath();

  }, 1000 / fps);
 }
animate();

и готовые планеты:

//солнце

 solus = function(xAxis, yAxis, radius) {
ctx.shadowBlur=400
ctx.shadowColor="red"
ctx.fillStyle ="#ff9900";
ctx.beginPath(); 
ctx.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false)     
ctx.fill();
ctx.shadowBlur = 0;
}

//Fighting Pits
pits = function(xAxis, yAxis, radius) {
ctx.beginPath();
ctx.fillStyle ="#990000"
ctx.arc(xAxis, yAxis, radius, 0, Math.PI , false)     
ctx.moveTo(xSpot1,ySpot1)
ctx.lineTo(xSpot1,ySpot2)
ctx.lineTo(xSpot2,ySpot2)
ctx.lineTo(xSpot2,ySpot3)
ctx.lineTo(xSpot3,ySpot4)
ctx.lineTo(xSpot4,ySpot3)
ctx.lineTo(xSpot4,ySpot2)
ctx.lineTo(xSpot5,ySpot2)
ctx.lineTo(xSpot5,ySpot1)
ctx.lineTo(xSpot1,ySpot1)
ctx.fill();

} 



 //Water Planet

 roa = function(xAxis, yAxis, radius) {
 ctx2.shadowBlur = 0;
 ctx2.beginPath(); 
 ctx2.fillStyle ="#00ffff"
 ctx2.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false) 
 ctx2.fill();

 }


//Forest planet atmoshpere
eldridA = function(xAxis, yAxis, radius) {
ctx.beginPath(); 
ctx.fillStyle ="rgba(230, 230, 230, 0.3)";
ctx.arc(xAxis, yAxis, radius, 0, Math.PI * 2, false) 
ctx.fill();

}
//forest core
eldrid = function(xAxis, yAxis, radius) {
ctx.shadowColor = "rgba(230, 230, 230, 0.2)";
ctx.shadowBlur = 200;
ctx.beginPath(); 
ctx.fillStyle ="#ff9900"
ctx.arc(xAxis, yAxis, radius / 2, 0, Math.PI * 2, false) 
ctx.fill();
xAxis2 = xAxis - window.innerWidth * 0.009 
yAxis2 = yAxis + window.innerHeight * 0.007
ctx.arc(xAxis2, yAxis2, radius / 4, 0, Math.PI * 2, false) 
ctx.fill();
ctx.beginPath();
xAxis3 = xAxis + window.innerWidth * 0.011
ctx.arc(xAxis3 , yAxis2, radius / 3, 0, Math.PI * 2, false) 
ctx.fill();
ctx.beginPath();
yAxis3 = yAxis - window.innerHeight * 0.03 
ctx.arc(xAxis, yAxis3, radius / 3, 0, Math.PI * 2, false) 
ctx.fill();
ctx.shadowBlur = 0;
ctx.shadowColor = null;
}

Итак, как я могу заставить более одной планеты вращаться вокруг Солнца? любая помощь приветствуется.


person Neb    schedule 18.01.2017    source источник


Ответы (1)


Я сделал простую демонстрацию солнечной системы с несколькими планетами, используя холст: http://codepen.io/giladaya/pen/PWWKLP

Я считаю, что вы можете легко адаптировать его к своим потребностям, и я объясню основные части кода:

Каждая планета имеет свои собственные свойства, такие как радиус, расстояние от центра, радиальная скорость и ссылка на функцию рисования.

var planets = [
  {
    name: 'sun',      // for reference
    rad: 30,          // Planet radius
    distance: 0,      // Planet distance from center
    rv: 0,            // radial velocity (deg/sec)
    drawFunc: drawSun // draw function
  },
  {
    name: 'foo',
    rad: 10,
    distance: 70,
    rv: 1,
    drawFunc: drawBlue
  },
  {
    name: 'bar',
    rad: 15,
    distance: 100,
    rv: 2,
    drawFunc: drawRed
  }
];

Основной цикл выполняет итерацию по всем планетам, обновляет их текущий угол в соответствии с радиальной скоростью и рисует каждую из них в новом обновленном местоположении.

function draw() {
  ctx.fillRect(-cW/2, -cH/2, cW, cH);

  var now = Date.now(), 
      dts = (now - lastFrameTime) / 1000;
  planets.forEach(function(planet, idx){
    var theta = 0;
    planetsAngle[idx] += planet.rv/Math.PI * dts;
    theta = planetsAngle[idx];
    var x = planet.distance * Math.cos(theta);
    var y = planet.distance * Math.sin(theta);
    planet.drawFunc(ctx, x, y, planet.rad);
  });
  lastFrameTime = now;
  requestAnimationFrame(draw);
}

Обратите внимание, что при использовании requestAnimationFrame вам не нужно устанавливать таймеры.

Функция рисования для каждой планеты может быть настолько сложной, насколько вы хотите, чтобы на планете было больше элементов. Например:

function drawRed(ctx, x, y, rad) {
  ctx.save();
  ctx.fillStyle = 'red';
  ctx.translate(x, y);
  ctx.beginPath();
  ctx.arc(0, 0, rad, 0, 2*Math.PI , false);
  ctx.fill();
  ctx.fillStyle = '#A00';
  ctx.fillRect(-4, -4, 8, 8);
  ctx.restore();  
}
person Giladd    schedule 18.01.2017
comment
Спасибо, Гиладд, он мне очень поможет и позволит мне закончить завтра. - person Neb; 19.01.2017