0

I’m new to JavaScript (and programming) and am struggling with how to add rotation in a HTML5 Canvas. I’m basically trying to get a JavaScript object to rotate around another object. In my case I need to get a planet to orbit around the sun.

I currently have the planets declared within the draw function and they display fine. I just need help on how to add rotation.

Thanks for your time.

1
  • You need to re-position the objects and re-draw the canvas. Commented Nov 27, 2012 at 18:25

1 Answer 1

2

Here's a simple example: http://jsfiddle.net/FTMCv/1/

The CelestialBody class that I've created only accounts for circular orbits, so it's not a perfect simulation, but it might suffice in most instances.

(function(){

    var can = document.getElementById('planetarium'),
        ctx = can.getContext('2d'),
        bodies = [];


    (function init(){
        var orbCenter = {x:can.width/2, y:can.height/2};

        bodies.push(new CelestialBody(
            50, orbCenter , 0, 0));

        bodies.push(new CelestialBody(
            15, orbCenter , 250, -.2));
        bodies.push(new CelestialBody(
            6, orbCenter , 200, .3));
        bodies.push(new CelestialBody(
            7, orbCenter , 150, .5));
        bodies.push(new CelestialBody(
            5, orbCenter , 100, 1));
        bodies.push(new CelestialBody(
            4, orbCenter , 75, 3));
    })();

    function CelestialBody(radius, orbitalCenter, orbitalDistance, orbitalVelocity){
        var pos = {x:0, y:0},
            rad = radius,
            orb = {x: orbitalCenter.x, y:orbitalCenter.y},
            ove = orbitalVelocity,
            odi = orbitalDistance;

        var update = function(){
            var cAng = Math.atan2(pos.y - orb.y, pos.x - orb.x);
            var rAng = cAng + ove * Math.PI/180;

            pos.x = orb.x + Math.cos(rAng) * odi;
            pos.y = orb.y + Math.sin(rAng) * odi;
        };

        this.draw = function(ctx){
            update();

            ctx.beginPath();
            ctx.fillStyle = "#fff";
            ctx.arc(pos.x,pos.y, rad, 0, 2*Math.PI);
            ctx.fill();
        };

        (function init(){
            pos.y = orb.y;
            pos.x = orb.x + odi;
        })();
    }

    (function draw(){
        ctx.clearRect(0,0,can.width,can.height);

        for(var i = 0; i < bodies.length; i++)
            bodies[i].draw(ctx);

        webkitRequestAnimationFrame(draw);
    })();

})();​
Sign up to request clarification or add additional context in comments.

6 Comments

If I were to expand this to include satellites, I would make them a property of the CelestialBody class, and use the parent's current position as their orbitalCenter.
Thanks for your response but when I click on the JSFiddle link the planets don’t rotate?
Right now it will only work in webkit browsers (like Chrome). If you change webkitRequestAnimationFrame to mozRequestAnimationFrame it will work in FireFox.
Ideally, you'd include a polyfill for requestAnimationFrame and use that.
Yes, you would simply add that to the parameters and pass it in when constructing the CelestialBody
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.