Анимированное вращение фотографий с JavaScript

Анимированное вращение фотографий с JavaScript

В процессе работы над одним интересным проектом, возникла задача поворота фоток, которые загружет пользователь.

Можно было, конечно, обойтись просто поворотом на серверной стороне и отобразить обновленную фотку, но хотелось сделать так, чтобы фотка поворачивалась на клиенте, да еще с анимашками и, разумеется, чтобы везде работало.

В итоге получилось давольно-таки неплохо.

Начал я с поиска каких-нибудь готовых инструментов. Нашел нечто под названием wilq32.rollimage.

Этим инструментом мы и воспользуемся.

Чтобы все было понятно, приведу код демостранички. На ней не будет ничего, кроме кнопок для управления поворотами и фотографии с враппером.

HTML:

  <div id="Actions">
<span id="clockwise">
Clockwise
</span>
<span id="anticlockwise">
Anticlockwise
</span>
</div>
<div id="image">
<img id="img1" src="image.jpg" />
</div>

А для того, чтобы все это работало в IE, сразу после body пишем:

<style>v\:image { behavior:url(#default#VML); display:inline-block }</style>    
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />

Обработку кликов управляющих кнопок вешаем на $(document).ready

 $(document).ready(function() {
$('#Actions span').click(function() {
switch (this.id) {
case "clockwise":
Rotate($('#img1'), 90);
break;
case "anticlockwise":
Rotate($('#img1'), -90);
break;
}
});
});

 Теперь, собственно, приступим к наворотам с поворотами.


function BindRotation() {
function SetMargin(id, mt) {
if ($('#' + id).is('span')) {
$('#' + id + ' canvas').css({ marginTop: -mt })
} else {
setTimeout(function() { SetMargin(id, mt) }, 2);
}
};
$('#image img').each(function() {
var w = $(this).width();
var h = $(this).height();
var newDimensions = Math.round(Math.sqrt(w * w + h * h));
mt = (newDimensions - h) / 2;
$('#image img').rotate(0);
var id = this.id;
setTimeout(function() { SetMargin(id, mt) }, 2);
});
};

$(window).load(function() {
BindRotation();
});

 

Сразу обращаю ваше внимание на то, что BindRotation я вешаю на $(window).load. Это необходимо для того, чтобы изображения, которые мы будем поворачивать уже были загружены, чтобы мы могли получить их размеры.

Разбираем по строчкам

$('#image img').rotate(0);

Эта функция создаст квадратный canvas, размер стороны которого будет

Math.round(Math.sqrt(w * w + h * h));// это теорема Пифагора

Изображение будет распологаться ровно посередине этого канваса. Для того, чтобы не было никаких скачков изображения, запускаем

 SetMargin(id, mt)//, где mt = (newDimensions - h) / 2;

Вот, собственно, почти все. Осталось объявить функцию Rotate, которая будет производить поворот.

function Rotate(image, grad) {
angle = parseInt(image.attr('angle'));
if (angle) {
angle = angle + grad;
} else {
angle = grad;
}

image.attr('angle', angle);
if ($.browser.msie) {
image.rotate(angle);
} else {
image.rotateAnimation(angle);
}
}

Как видите, для IE я делаю поворот без анимации. Несмотря на то, что возможность анимировать поворот в IE есть, лучше все-таки без анимации.

Лучше тысячи слов скажем мой исходный код:

Демо Скачать

Расскажите друзьям

Оцените статью:
  • 1
  • 2
  • 3
  • 4
  • 5

Комментарии — 16

MoLoT
В опере 9.64, изображение не крутится.
dijay
Не вижу практического применения.
#
dijay
Илья
MoLoT обновляться не пробовали на 10?
dijay
Илья, это все равно, что пользователям с ИЕ6 и ИЕ5.5 сказать «Обновляться не пробовали»? :-)
#
dijay
Igor
10.10 тоже не вращается
Андрей
Ну применение то найти можно, а вот как изменения записать в базу ...? Т.е. после того, как пользователь загрузит фотку, перевернёт, и ... мне нужно сохранить в базу её ориентацию или угол .. Вообще, что сохранять?
Евгений
Андрей, я в конце функции Rotate добавляю функцию RotateServer, которая посылает ajax-запрос с ID фотки и угол поворота.
Как правило, фотка еще не заканчивает поворачиваться, а уже приходит ответ от сервера, что все фотки повернуты (их три штуки разных размеров)

Бродяга, там используется та же библиотечка.
Kykyryzo
Практическое применение придётся поискать))
Евгений
Это дело практически применимо везде, где пользователь загружает фотографии.
На сервисах типа фликр, пикасавеб, вконтакте и фэйсбук, твитпик и так далее.
Впервые такой анимационный поворот увидел в Пикасе. Мне понравилось, еще тогда хотел сделать такую же штуку на js.

Кстати, про Оперу. И правда не работает. Хотя точно до выхода 10.5 тестировал это на 10.1. Поищу. Если найду в чем косяк, сделаю апдейт статьи.
mmaarrina
Это дело практически применимо везде, где пользователь загружает фотографии.

Не, в таких местах флеш и только флеш. Но тем не менее, спасибо за пример. Уже придумал где можно такое использовать, правда в качестве "фишки"))))))))
Антон
Согласен с mmaarrina бы ло бы хорошо сделать поворот не только на 90 градусов а на любой количество(произвольно мышкой). Но всё равн, Жень, спасибо за пример
#
Антон
крут
опа, круто дождался наконец то, а то голову нужно поворачивать
Алексей
В Mazill-e не работает :( Почему??
Frost
Если бы можно было сохранять.....
#
Frost
Константин С.
Ув.Автор, спасибо за отличную заметку!

Огромнейшая просьба, если можете - немного изменить результат данного скрипта - Думаю многим тоже моя идея будет по нраву.

Если возможно - сделайте в примере (или в отдельном :) ) - С таким условием, чтобы действие поворота происходило сразу при наведении картинки; !и если можно конечно сделать это ввиде (повторного, и быстрого - до 4-8 раз) "шатания" вправо-влево > и поворот картинки например на 15 гр.

Спасибо.!

Новый комментарий

как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть
как выглядит какой тег
жирный текст <b>жирный текст</b>
курсивный тект <i>курсивный тект</i>
зачеркнутый текст <s>зачеркнутый текст</s>
подчеркнутый текст <u>подчеркнутый текст</u>
ссылка <a href="адрес">ссылка</a>
function foo() { ... }
<pre><code>function foo() { ... } </code></pre>
разрешенные теги или посмотреть как будет выглядеть

metin2 pvp metin2 pvp serverler pvp serverler