Поворот изображении с помощью SVG и VML

11 Декабрь 2008

Некоторое время назад наткнулся на оригинальную реализацию фотогаллеерей на флэше под названием Polaroid Gallery. И задумался а можно ли реализовать все это с помощью Javascript'a. Единственная загвоздка была в повороте картинок.

В последней версии браузера Safari, а также в Firefox'e с версии 3.1 ввели CSS своиство Transforms. В этом свойстве, есть замечательная функция rotate, которая позволяет поворачивать блоки. Но к сожалению ни в Opera, ни в Firefox 2,3, ни конечно же в IE свойство Transforms не реализовано. Так что проблема с поворот картинок осталась.

Немного погуглив и почитав документацию, нашел что в SVG есть атрибут transform, и в этом атрибуте присутствует команда rotate, которая собственна и поворачивает блок на заданый угол. Давайте попробуем все это реализовать на примере.

Создаем пустой html документ. Прописываем блок с абсолютным позиционированием и с помощью элемента object прикрепляем SVG фаил. К сожалению прописать SVG код прямо в html документе не получится из-за плохой поддержки браузерами данной технологии, так что получаем дополнительный запрос к серверу.

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. </head>
  6. <body>
  7. <div style="position: absolute;"><object type="image/svg+xml" data="test.svg" name="owMain" width="600" height="650"></object></div>
  8. </body>
  9. </html>

Теперь создаем пустой SVG документ и прописываем в нем тег image со всеми нужными атрибутами.

  1. <?xml version="1.0" standalone="no"?>
  2. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  3. <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  4. <image x="100" y="100" width="300px" height="300px" xlink:href="test.jpg" transform="rotate(10)">
  5. <title>Image title</title>
  6. </image>
  7. </svg>

С атрибутами тут все просто: отступ слева, отступ сверху, ширина, высота, путь к картинке. Ну и последнии самый важный атрибут transform с 3-мя заданными значениями в команде rotate. Первое значение указывает на сколько градусов должно повернуться изображение. Остальные 2 указывают на точку опоры, относительно которой будут вращаться картинка. Лучше реализовать точку опоры в центре картинки, для этого делим высоту и ширину картинки пополам и к этим значениям плюсуем отступы y и x соотвественно (если конечно они есть)

Смотрим, что получилось:

Как видим в Firefox и Opera появились небольшие зубчики по краям изображения. В Safari же все отрендерилось хорошо. Решить же частино проблему можно задав полупрозрачную тенюшку вокруг изображения.

Все бы хорошо, да вот всеми нелюбимый Internet Explorer, к сожалению не поддерживает SVG. Зато в нем реализован другой векторный формат под названием VML. И самое интересное в том, что с помощью него реализовать поворот блоков намного проще, чем с помощьюю SVG. Нужно в наш html документ добавить всего 3 строчки:

  1. <style>v\: * { behavior: url(#default#VML);display:inline-block }</style>
  2. <xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>
  3. <div style="position: absolute;"><v:image src="test.jpg" style="width:300px; height:300px; rotation: 10; margin: 100px 0 0 100px;" /></div>

2 первые строчки обязательны, если в html документе присутствует vml код. Ну и 3-ая строчка представляет собой блок со вставленной внутри картинкой. За поворот отвечает css свойство rotation в значении задается градус поворота картинки. Преимущества очевидны: ни дополнительного фаила, а это лишнии запрос к серверу, ни атрибутов, все можно задать через стили.

Смотрим, что у нас получилось в ie:

Как видим отрендерилось все четко. Так что в этом случае IE по всем параметрам уделал альтернативные браузеры.

Теперь разделим код с помощью Conditional Comments и смотрим получившийся результат. К слову поворачивать можно не только картинки, а любые элементы.

Метод работает в браузерах: Firefox 2+, Safari 3.1+, Opera 9+, IE6+.

Комментарии (15):

  • yura

    Прикольно, наткнулся сейчас на пункции gd библиотеки php. Сижу, балуюсь с поворотом картинок))

    13 Март 2009 | 11:59
  • yura

    Хочу подписаться на статьи RSS ,а не могу(( HELP!!!
    Страница с feed не грузится((

    13 Март 2009 | 12:20
  • admin

    Вот линк http://0range.ru/feed
    вроде все должно работать :) ну у меня во всяком случае все ок :)

    13 Март 2009 | 12:24
  • yura

    Да, работает, чере фаерфикс(Fierfox) подписался, а опера-собака))

    13 Март 2009 | 12:28
  • admin

    Хммм странно в firefox и google reader все хорошо щас пойду в опере проверю

    13 Март 2009 | 12:33
  • admin

    В опере 9.64 все работает :) Может версия просто старая?

    13 Март 2009 | 12:35
  • yura

    10.00 alpha ))

    13 Март 2009 | 12:37
  • admin

    ааа ну так это альфа :) а так rss вордпрессом генерируется, там все по умолчанию я ничего не менял

    13 Март 2009 | 12:39
  • yura

    так у меня тоже вордпрес, 2.7, но фид правда через feedburner генерится, и всё работает в этой 10-ке.

    13 Март 2009 | 12:41
  • BOLK

    В текст страницы SVG можно внедрить через data URL. Посмотри, у меня на сайте так время вертикально написано.

    13 Март 2009 | 17:08
  • admin

    Ну тада и запросов лишних к серваку не буит :)
    Кстати ты куда из жаббера пропал? Сообщения те не отправляются :((

    13 Март 2009 | 17:20
  • BOLK

    Пользуюсь корпоративным, надо и внешний включить, да.

    14 Март 2009 | 14:40
  • Tomas

    В IE8 картинка просто не отображается. Отображается в Compatibility View.

    23 Июль 2009 | 21:14
  • admin

    Да в ие8 были внесены изменения в VML
    v\: * { behavior: url(#default#VML);display:inline-block }
    насколько я знаю эта строчка не будет работать в ие8, надо задавать для каждого отдельного элемента

    23 Июль 2009 | 21:45
  • fantom

    люди,выручайте нужно повернуть (DIV id="child") в (DIV id="parent"), нужно задавать ЦЕНТР вращения и угол

    2 Октябрь 2009 | 12:33