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

3 марта 2010, 20:31 Евгений Белодед JavaScript рейтинг +17-

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

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

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

Начал я с поиска каких-нибудь готовых инструментов. Нашел нечто под названием 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 есть, лучше все-таки без анимации.

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

Демо Скачать

Рекламное место, которое может стать вашим

Понравилась статья?

Тогда подпишись на обновления через RSS или воспользуйся
другими способами подписки.

Читать в Яндекс.Ленте Добавить в Google Добавить в Netvibes
  •  

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

RSS
  • Аватарка
    4 марта в 8:38 ]]>MoLoT]]>
    В опере 9.64, изображение не крутится.
  • Аватарка
    4 марта в 9:37 dijay
    Не вижу практического применения.
  • Аватарка
    4 марта в 10:02 ]]>Илья]]>
    MoLoT обновляться не пробовали на 10?
  • Аватарка
    4 марта в 10:05 dijay
    Илья, это все равно, что пользователям с ИЕ6 и ИЕ5.5 сказать «Обновляться не пробовали»? :-)
  • Аватарка
    4 марта в 14:17 ]]>Igor]]>
    10.10 тоже не вращается
  • Аватарка
    4 марта в 15:23 ]]>Андрей]]>
    Ну применение то найти можно, а вот как изменения записать в базу ...? Т.е. после того, как пользователь загрузит фотку, перевернёт, и ... мне нужно сохранить в базу её ориентацию или угол .. Вообще, что сохранять?
  • Аватарка
    4 марта в 15:48 ]]>Севастопольский Бродяга]]>
    Ещё вот тут подобный эффект, тоже прикольно http://romka.eu/blog/jquery-image-rotate
  • Аватарка
    4 марта в 18:34 ]]>Евгений]]>
    Андрей, я в конце функции Rotate добавляю функцию RotateServer, которая посылает ajax-запрос с ID фотки и угол поворота.
    Как правило, фотка еще не заканчивает поворачиваться, а уже приходит ответ от сервера, что все фотки повернуты (их три штуки разных размеров)

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

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

    Не, в таких местах флеш и только флеш. Но тем не менее, спасибо за пример. Уже придумал где можно такое использовать, правда в качестве "фишки"))))))))
  • Аватарка
    10 марта в 12:39 Антон
    Согласен с mmaarrina бы ло бы хорошо сделать поворот не только на 90 градусов а на любой количество(произвольно мышкой). Но всё равн, Жень, спасибо за пример
  • Аватарка
    11 марта в 22:09 ]]>крут]]>
    опа, круто дождался наконец то, а то голову нужно поворачивать
  • Аватарка
    25 марта в 5:00 ]]>Алексей]]>
    В Mazill-e не работает :( Почему??
  • Аватарка
    2 апреля в 15:36 Frost
    Если бы можно было сохранять.....
  • Эл. почта (используется для Граватарки)
  • Домашняя страница
  • Имя в Твиттере
  • Разрешенные теги Текст сообщения (надо бы заполнить это поле)
  • как выглядит какой тег
    жирный текст <b>жирный текст</b>
    курсивный тект <i>курсивный тект</i>
    зачеркнутый текст <s>зачеркнутый текст</s>
    подчеркнутый текст <u>подчеркнутый текст</u>
    ссылка <a href="адрес">ссылка</a>
    function foo() { ... }
    <pre><code>function foo() { ... } </code></pre>