В рамках создания нашей браузерной космической игры, перед нами стояла задача разработать простую и наименее ресурсозатратную анимацию вращения планет в звездной системе.Вычеркиваем
После непродолжительного подбора различных способов реализации, сразу были исключены варианты:
с gif-анимацией(из-за низкого качества изображения);с Flash(по договоренности, Flash-технологии решили в проекте не использовать);с анимацией с помощью JQuery посредством функции $().animate(по причине ее прожорливости).
CANVAS в помощь!
Итак, остановились мы на использовании Canvas и JavaScript, посчитав этот вариант оптимальным для реализации нашей задачи.
Пофантазируем...
Любым доступным способом находим, рисуем или генерируем карту нашей будущей планеты. Предположим, у нас это будет экзопланета, где есть вода и растительность. Выглядеть карта нашей планеты будет примерно так:

Нам необходимо половину изображения скопировать и добавить с правой стороны, т.к. наша карта будет двигаться по поверхности canvas-блока, и при крайнем положении начинать движение заново. Результат получается таким:


Создаем планету
В качестве космического пространства у нас выступит блок div с любым подходящим для этого бэкграундом, а внутри разместим элемент с id=«planet»:
<div style="background-image:url(space.jpg); width:1000px; height: 1000px;"> <canvas id="planet" width="300" height="300" style="position: absolute; left:200px; top: 200px;"> </canvas> </div>
Далее заставляем нашу карту двигаться внутри созданного элемента canvas, который скоро превратится в планету:
$(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 мс. });
В результате произведенных действий, получаем примерно такую картину:

Закругляем...
Квадратных планет еще не открыли, поэтому придадим нашему небесному телу более привычный вид, прописав в style нашего элемента canvas border-radius на 50 процентов. Получаем:

Уже лучше, однако по-прежнему нет ощущения, что перед нами сферический объект.
Теперь подготовим в графическом редакторе круг с тенью по краям и бликами. Он должен быть обязательно полупрозрачным, т.к. мы будем накладывать его на нашу планетарную карту. В оригинале он будет выглядеть так:

Сейчас добавляем в нашу анимацию эффект вращения, а также, накладываем подготовленную картинку с тенями поверх карты планеты.
Финальный код нашей анимированной планеты получается таким:
<div style="background-image:url(space.jpg); width:1000px; height: 1000px;"> <canvas id="planet" width="300" height="300" style="position: absolute; left:200px; top: 200px; border-radius:50%"> </canvas> </div>
И код самой анимации:
$(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 мс. });
Финальный результат анимации планеты в игре:


Все вопросы и предложения по улучшению этого варианта реализации буду рад увидеть в комментариях.
Спасибо за внимание!
