22 декабря 2015
3 марта 2010
16
Анимированное вращение фотографий с 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 есть, лучше все-таки без анимации.
Лучше тысячи слов скажем мой исходный код:
Как правило, фотка еще не заканчивает поворачиваться, а уже приходит ответ от сервера, что все фотки повернуты (их три штуки разных размеров)
Бродяга, там используется та же библиотечка.
На сервисах типа фликр, пикасавеб, вконтакте и фэйсбук, твитпик и так далее.
Впервые такой анимационный поворот увидел в Пикасе. Мне понравилось, еще тогда хотел сделать такую же штуку на js.
Кстати, про Оперу. И правда не работает. Хотя точно до выхода 10.5 тестировал это на 10.1. Поищу. Если найду в чем косяк, сделаю апдейт статьи.
Не, в таких местах флеш и только флеш. Но тем не менее, спасибо за пример. Уже придумал где можно такое использовать, правда в качестве "фишки"))))))))
Огромнейшая просьба, если можете - немного изменить результат данного скрипта - Думаю многим тоже моя идея будет по нраву.
Если возможно - сделайте в примере (или в отдельном :) ) - С таким условием, чтобы действие поворота происходило сразу при наведении картинки; !и если можно конечно сделать это ввиде (повторного, и быстрого - до 4-8 раз) "шатания" вправо-влево > и поворот картинки например на 15 гр.
Спасибо.!