Recipe for the rotation of planets in space on HTML5 + JavaScript

    imageAs part of the creation of our browser-based space game, we were faced with the task of developing a simple and least resource-intensive animation of the rotation of the planets in the star system.

    Cross out


    After a short selection of various implementation methods, the options were immediately excluded:
    • with gif-animation (due to poor image quality);
    • with Flash (by agreement, Flash-technologies decided not to use in the project);
    • with animation using jQuery using the $ (). animate function (due to its gluttony).


    CANVAS to the rescue!


    So, we stopped using Canvas and JavaScript, considering this option optimal for the implementation of our task.

    We’ll fantasize ...

    In any available way, we find, draw or generate a map of our future planet. Suppose we have this exoplanet, where there is water and vegetation. The map of our planet will look something like this:

    image

    We need to copy half the image and add it on the right side, because our map will move along the surface of the canvas block, and in the extreme position, start moving again. The result is as follows:

    image

    image

    Create a planet

    As outer space, we will have a div block with any suitable background for this, and inside we place an element with id = "planet":


    Next, we make our map move inside the created canvas element, which will soon turn into a planet:

     $(function(){
            var pl_id = 'planet';
    	var image = new Image();
    	image.src = 'images/planets/1/1/map.jpg';
            // определяем длину и высоту элемента canvas
    	var width = $('#'+pl_id).width();
    	var height = $('#'+pl_id).height();
    	var canvas = document.getElementById(pl_id);
    	var id = canvas.getContext("2d");
    	var newMoveWidth = 0;
    	var newMoveHeight = 0;
    	var drawPl = function(){
    	     id.clearRect(0, 0, width, height);
                 // рисуем карту с новыми координатами внутри элемента
    	     id.drawImage(image, newMoveWidth, newMoveHeight, width, height, 0, 0, width, height); 
    	     if (newMoveWidth >= 899.5) newMoveWidth = 0; // если смещение достигло предела, начинаем сначала
    	     else newMoveWidth = newMoveWidth+0.5; // иначе двигаем карту дальше
    	}
            setInterval(drawPl, 50); // запускаем анимацию со скоростью 50 мс.
     });
    

    As a result of the actions taken, we get approximately the following picture:

    image

    Round off ...


    Square planets have not yet been opened, so we will give our celestial body a more familiar look by writing canvas border-radius to 50 percent in the style of our element. We

    image

    get : Already better, but still there is no sensation that we have a spherical object.

    Now, prepare a circle with a shadow on the edges and highlights in the graphics editor. It must be necessarily translucent, because we will overlay it on our planetary map. In the original, it will look like this:

    image

    Now we add the rotation effect to our animation, and also, we overlay the prepared picture with shadows on top of the planet map.

    The final code for our animated planet is as follows:


    And the animation code itself:

    $(function(){
            var pl_id = 'planet';
    	var image = new Image();
    	image.src = 'map2.jpg';
            // загружаем изображение тени и бликов планеты
    	var fxShadow = new Image();
    	fxShadow.src = 'planet_shadow.png';
            // определяем длину и высоту элемента canvas
    	var width = $('#'+pl_id).width();
    	var height = $('#'+pl_id).height();
    	// рассчитываем угол вращения планеты
    	var beta = 360/900;
    	var beta = (beta*Math.PI)/360;
    	var l = (Math.sqrt(width*width+width*width))/2;
    	var gam = Math.PI - ((Math.PI - (beta * Math.PI)/360)/2) - (Math.PI/4);
    	var b = 2*l*Math.sin(beta/2);
    	var x = b*Math.sin(gam);
    	var y = b*Math.cos(gam);
    	var p1 = Math.cos(beta);
    	var p2 = Math.sin(beta);
    	var canvas = document.getElementById(pl_id);
    	var id = canvas.getContext("2d");
    	var newMoveWidth = 0;
    	var newMoveHeight = 0;
    	var drawPl = function(){
    	        id.clearRect(0, 0, width, height);
    		// применяем к нашей планете вращение
    		id.transform(p1, p2, -p2, p1, x, -y);
                    // рисуем карту с новыми координатами внутри элемента
    		id.drawImage(image, newMoveWidth, newMoveHeight, width, height, 0, 0, width, height); 
                    //добавляем тень и блики
                    id.drawImage(fxShadow, 0, 0, width, height);
                    // если смещение достигло предела, начинаем сначала
    		if (newMoveWidth >= 899.5) newMoveWidth = 0; 
    		else newMoveWidth = newMoveWidth+0.5; // иначе двигаем карту дальше
    	}
            setInterval(drawPl, 50); // запускаем анимацию со скоростью 50 мс.
     });
    

    The final result of planet animation in the game:

    image

    image

    I will be glad to see all questions and suggestions for improving this implementation option in the comments.

    Thanks for attention!

    Also popular now: