JavaScript

индекс
246,38

Плавная смена картинок — Javascript, SVG и VML

На одном из разрабатываемых сайтов (школа боевых искусств) необходимо было разместить иконки с видами спорта, которые есть в этой школе. В итоге дизайнер предложил такое решение:

image

Чем порадовал и нас самих, и заказчика. Естественно к этой красоте должны были прилагаться такие эффекты как всплытие наверх картинки при наведении и выделение цветом картинки. Встал вопрос как технически реализовать.


Мысль о Flash'е я отверг весьма быстро, потому что

1. своего человека, хорошо знающего flash в команде нет

2. у меня стоит блокировка flash'а всего по умолчанию, ибо чаще всего там только реклама (привет, хабр)

3. нужен плагин — понятно что он стоит на 95% машин, но все же

4. зачем flash, если так можно и на js + svg/vml?

Писать родными методами с нуля на SVG (для нормальных браузеров) и VML (для IE, там поддержка SVG только через плагин) не хотелось — была найдена отличная либа raphael от нашего русского разработчика Дмитрия Барановского (кстати он есть на хабре, но ник не помню, побликаций по рафаэлю у него на хабре нет).

Достаточно быстро из всех рисунков было собрано то что было на макете — они были размещены и повернуты конструкцией такого вида:

var R = Raphael(«top_sports», 665, 274); //создаем поле для рисования, top_sports — id дива, цифры — размер поля

var img_wushu = R.image(«wushu.png», 0, 75, 178, 137).animate({rotation: 2}, 0); //создаем изображение в координатах 0,75 размером 178x137 и поворачиваем на 2 градуса, 0 после 2 означает что повернуть надо моментально

Как видно — все крайне просто, понятно и красиво.

После этого встал вопрос, как сделать чтоб картинки всплывали наверх при наведении. Для этого необходимо повесить небольшой обработчик, что также делается легко и просто:

$(img_wushu.node).mouseover(function(evt) {img_wushu_back.toFront();});

Теперь картинки при наведении стали моментально отображаться сверху, что было уже лучше чем ничего, но все таки весьма некрасиво. Хотелось чтоб картинка постепенно появлялась на верху, давая пользователю осознать происходящее. Однако метод toFront вгонял в уныние своей безаппеляционностью… И решение конечно же было найдено — наверное сказались попытки гейм-дева и множество прочитанных статей по теме.

Появилась мысль сделать всплытие картинки дополнительным слоем, который будет сперва отправляться toFront, а потом будет менять прозрачность с 0 до 100. Плюс потребуется пара мелких действий, кои я объясню по ходу.

Сперва создаем для каждого спорта две картинки:

var img_wushu = R.image(wushu_src, 0, 75, 178, 137); //создали основную картинку

var img_wushu_back = R.image(wushu_src, 0, 75, 178, 137).hide().animate({rotation: 2}, 0).toBack().show(); //создали, скрыли, повернули, отправили назад и там уже показали картинку, которую будем использовать для плавности

img_wushu.animate({rotation: 2}, 0); //повернули основную картинку

Поворот основной картинки лишь в конце происходит чтоб пользователь гарантированно не имел шансов увидеть создание второй картинки и какое-то мелькание связанное с этим. В принципе все происходит быстро и мне такого эффекта заметить не удавалось, но все же слегка перестраховался.

Теперь новый обработчки onmouseover (используя jquery):

$(img_wushu.node).mouseover(function(evt) {

img_wushu_back.attr({opacity:0}). //картинку используемую для плавности делаем полностью прозрачной

toFront(). //кладем ее на самый верх

animate({opacity:1},500); //и медленно, за пол секунды материализуем ее перед пользователем

setTimeout(function(){img_wushu.insertAfter(img_wushu_back);},501);}); //после того как промежуточная картинка стала непрозрачной, ложим на нее основную картинку, причем ложим уже не toFront, так сверху уже может всплывать другая картинка, а ложим ее поверх промежуточной картинки.

Вот и все решение — получилось весьма оригинально. Кроссбраузерно — IE6+, Opera, FF, Safari, наверное и Chrome, но в нем не проверял. Отдельным плюсом можно отметить что работает даже в Opera Mobile. Может будет работать в последнем мобильном IE, но проверить это не могу.

Тут можно увидеть живой пример получившегося.

P.S. Кросс-пост из blog.itea-lab.ru во избежание Х-эффекта

update Надо конечно как-то автоматизировать это все, чтоб добавление каждой картинки делалось с одной краткой строки — или плагин для raphael оформить, или хотя бы функцию завернуть. Но это уже бытовые мелочи, которые по ходу решим. :)

update 2 Все таки сервер накрыло. Хорошо так — даже по ssh не пускает. Как приотпустит — напишу.

update 3 Хабра-эффект временно отпустил. Можете продолжать. )

Ссылку на сайт школы дам в следующем посте, когда текущий пример доработаем, доделаем сайт в целом и слегка получше подготовимся к х-эффекту.

© Веб-студия iTea Lab — создание сайтов в Мурманске
+25
23 декабря 2009, 12:04
65

комментарии (84)

0
itspoma #
интересно =)
но как минус = надо на каждую картинку писать обработчик… а если картинок будет много?
надо бы подумать как упростить весь процесс добавления картинки…
0
DenisO #
Несомненно! Написал update :)
НЛО прилетело и опубликовало эту надпись здесь
0
nobr #
Ну, вообще-то можно обойтись одними картинками.
–8
trueowl #
ну вообще-то можно обойтись одним флешем :)
+1
DenisO #
С дивами скорее всего возникли бы проблемы, потому как картинки пришлось бы хранить перевернутыми и там будут прозрачные части, которые будут мешать. Плюс потом еще добавится рамка светящаяся (вернее будет подсвечиваться то что сейчас белое вокруг картинки) — можно конечно наштамповать эти рамки по размеру каждой картинки, но по моему лучше сделать более прогрессивно. :)
0
nobr #
Картинки можно поворачивать с помощью JS
0
z0rg #
в html 5 !?
0
z0rg #
уже нашел ответ :)
+4
Napolsky #
И до ресурсов думаю было бы не так прожорливо. А то совсем недавно кричали что вот мол флеш баннеры отъедают много, а здесь такое:

+1
Vayngarten #
Еще пример подобного эффекта, но на CSS
http://www.3site.eu/examples/gallery/

Только вот ресурсов тоже много съедается.
+1
sidus #
Не сразу допер как на этом примере посмотреть фото с машинкой.))
–5
homm #
Вы в курсе, сколько будут весить полупрозрачные PNG картинки с фотографиями? Не мелите чушь.
–2
homm #
Был бы рад выслушать кого-то, кто считает иначе.
0
sunnybear #
лучше бОльший размер, чем бОльшая загрузка проца
0
homm #
С чегО вы это взяли? Нагрузка в данном случае идет при взаимодействии пользователя со страницей, а не всегда, как в случае с флеш баннером. Это нормально, что мой процессор работает, когда мне от него что-то нужно.

Еще я бы отметил, что края картинок будут иметь форму квадрата, описывающего ромб фотографии. Сделать наведение на элементы под этим квадратом не получится.
0
sunnybear #
можно рассчитывать координаты при наведении. Не уверен, что это — лучший выход. Но что-то мне подсказывает, что сейчас зарождается новое зло — использование SVG/Canvas безо всякого представления о производительности. Как раньше было с Flash

И я не уверен, что подобная реализация на Flash постоянно бы грузила проц.
–1
homm #
использование SVG/Canvas безо всякого представления о производительности.
Я здесь этого не вижу.

Про флеш имеется ввиду не эта конкретная ситуация а, «А то совсем недавно кричали что вот мол флеш баннеры отъедают много, а здесь такое:».
0
sunnybear #
А я вижу :) Но суть не в этом. Просто данный пример (в статье) — это только первая ласточка. Скоро их будет много. И нужно будет думать, как автоматизировать решение таких проблем производительности.
0
fzn7 #
С чего вы взяли, что флеш баннер жрет проц постоянно? Если картинка не обновляется, флеш плеер не перерисовывает рабочую область.
+2
homm #
Где вы видели флеш-баннер без обновляющейся картинки? :)
0
fzn7 #
Ну это уже вопрос не по существу. В любом случае если обновляется часть картинки, плеер обновляет только часть картинки и тем самым экономит ресурсы. «Нагрузка в данном случае идет при взаимодействии пользователя со страницей, а не всегда, как в случае с флеш баннером» — При прочих равных фичах флеш будет быстрее и жрать меньше.
0
homm #
«Про флеш имеется ввиду не эта конкретная ситуация а, «А то совсем недавно кричали что вот мол флеш баннеры отъедают много, а здесь такое:».»
+1
deseven #
Привет из замкадья!
НЛО прилетело и опубликовало эту надпись здесь
0
ipod #
Я тоже сталкивался с этим. Перевести из JPEG в PNG не получалось без потери качества. PNG весил больше, иногда существенно, зависело от размера JPEG.
Может я что-то не так делал?
+1
homm #
Теперь я посмотрел пример, там уже используются PNG фотографии с полупрозрачностью. Так что вопрос не в том, на сколько может увеличится, а на сколько можно было бы уменьшить пример, сделав все правильно. Сейчас он весит пол метра.
0
Smerig #
В ИЕ8 есть некотрые баги: при наведении сначала показывается основная картинка сверху, потом поверх нее начинает появляться прозрачная картинка. После того, как появилась, рамка картинки начинает пульсировать.
+2
Hellplix #
выглядит немного убого :(
честно говоря лучше бы на флеше сделали.
+3
xxllexx #
если бы не было ИЕ или ИЕ был бы лучше, то можно было бы все это сделать на CSS3
–1
bolk #
Нельзя. Не смотря на то, что «топовые» версии браузеров используются всё чаще, но прежний версий тоже хватает, а их надо поддерживать.
0
xxllexx #
Это да, тогда лучше флешь он есть везде и одинаково во всех браузерах
+8
rinat_crone #
Не «ложим», а «кладём» или «накладываем». Простите, очень глаза режет.
–6
anycolor #
Кладут — в туалете.
0
Masterkey #
Х-эффект накрыл _http://blog.itea-lab.ru (
0
kost #
P.S. Кросс-пост из blog.itea-lab.ru во избежание Х-эффекта

Похоже, эффект его все же постиг. Ни пример, ни картинки не показываются.
0
LDZ #
Перезалейте хотя бы картинку на какой-нибудь фотохостинг. Ваш сайт Хабра-лёг
0
zlo #
а можно ссылку на сайт школы?
0
DenisO #
чуть позже, он еще в процессе
0
zlo #
ок, а в каком городе находится?
0
DenisO #
Мурманск
–3
Levsha100 #
Блин, намного легче, удобней, красивей было бы сделать на флэше, скрипт элементарный…
–2
Gunger #
Делали подобное для «Квартет-А» — www.kvartet-a.ru/portfolio/
+1
shiberz #
сделано убого — часть фоток просмотреть невозможно вообще, еще какую-то часть можно увидеть после усиленного пиксельхантинга
–2
Gunger #
Сделай лучше.
0
shiberz #
заплати — сделаю
–4
Gunger #
Назови цену.
0
shiberz #
10к с использованием библиотек
15к — нативный js
–5
Gunger #
Дорого, даже по меркам Москвы.
0
shiberz #
корявая дешевая реализация на jquery у тебя уже есть.
–3
Gunger #
Пока, тролль ;-)
–1
shiberz #
гестапа обиделась, заплакала и ушла
–9
barbuza #
сосни хуйца
–4
Gunger #
Сколько же у тебя, недоношенного тролля, аккаунтов еще в запасе?
+2
shiberz #
слился, так не позорься.
barbuza — это не мой аккаунт
–3
Gunger #
barbuza — недодевелопер-гомосексуалист.
Ты, судя по вашей совместной реакции, его дружок, исполняющий его желания, изъявленные выше. Видно, посвящалось предложение пососать его немощных размеров половой орган (учитывая то, как он его называет) тебе, а не мне, дружок.
–5
barbuza #
спасибо, давно так не смеялся
+2
shiberz #
Ваша профессиональная и деловая несостоятельность — это не повод кидаться личными оскорблениями, в адрес незнакомых людей
–4
Gunger #
Тебе бы мою несостоятельность, уж поверь ;-)
+2
shiberz #
Оставьте свою несостоятельность при себе, и ступайте с миром. Вы не адекватны и не способны вести цивилизованный разговор.
–4
Gunger #
Приглядитесь, кто же начал про «сосни хуйца». Ровно с того момента разговор потерял для меня всякую смысловую нагрузку и стал меня смешить. Тролли — это весело.
+1
shiberz #
И каким образом это связано с вашим неадекватным поведением в отношении меня?
–3
Gunger #
А это уже напрямую связано со следующими нелицеприятными выражениями: «сделано убого», «корявая дешевая реализация на jquery», никак не подкрепленными Вашими гениальными способностями. Можете сделать лучше — сделайте. Не можете — не осуждайте чужие разработки.

Покажите уж работы свои, чтобы было с чем сравнивать хоть.
0
homm #
Товарищь, вы идиот, вам уже сказали, за сколько shiberz может и готов сделать лучше. Брать на «слабо» — это очень дешево.
–2
Gunger #
А это не «на слабо», это всего-то показатель Вашей с ним пустословности, товарищ уебан.
+1
n0s #
Может хватит? Уже второго постороннего человека говном обложил.
–3
Gunger #
Как будто я первый назвал этого уебана идиотом.
+1
shiberz #
Не надо подменять понятия. Мое мнение о корявости и убогости вашей разработки было подкреплено объективным фактом — реализация не выполняет свою основную задачу, не позволяет просмотреть выложенные фотографии без многократной перезагрузки страницы и длительного пиксельхантинга.
А Вы можете чем-то обосновать Ваше заявление «barbuza — недодевелопер-гомосексуалист.
Ты, судя по вашей совместной реакции, его дружок, исполняющий его желания, изъявленные выше. Видно, посвящалось предложение пососать его немощных размеров половой орган (учитывая то, как он его называет) тебе, а не мне, дружок.»?
–4
Gunger #
Можете продемонстировать свои первоклассные работы или Ваши слова не стоят и гроша?
+1
shiberz #
Т.е. по существу вопроса — обоснованность оскорблений в адрес незнакомых людей, Вам ответить нечего? Это первое.
Второе — стоимость моих слов никак не зависит от низкого качества Вашей работы.
Третье — демонстрировать что-либо человеку не умеющему себя вести, я лично считаю нецелесообразным.
Хотите продолжить общение в конструктивном ключе? — Вежливо извинитесь перед всеми кому здесь нахамили. Желаете продолжить осокрбления? — тогда давайте встретимся лично, благо находимся в Москве и это не составляет особого труда. Я предпочитаю чтобы гадости мне говорили в лицо, заодно не будет грязи на хабре.
–3
Gunger #
Телефон в личку.
0
shiberz #
телефон — это приватная информация, пишите в жабер — shiberz@jabber.ru
–1
homm #
Тролли — это те, для кого разговор не несет смысловой нагрузки. а только смешить. Теперь то ясно, кто есть кто, правда?
–2
Gunger #
Неправда, тролль.
–2
fzn7 #
На флеше это 4 часа работы + день на внедрение. По деньгам 3-5 килорублей.
0
shiberz #
а флеш тут причем?
–3
Gunger #
Ага, это более реальная стоимость данной задачи. Собственно, на js она тоже занимает примерно столько же времени и стоит аналогично, даже чуть меньше.
–1
nobr #
Забаньтесь.
0
samansay #
знакомый дизайн коллажа…

такой когда-то, помню, был на урбании'08 для списка участников.
0
Laughboy #
Как то была зацепила подобная идея. Сначала делал на обычных .jpg + jQuery.Rotate, все как бы хорошо кроме загрузки CPU :(
Далее переделал сам ротейт на сторону ImageMagick, а эффекты на jQuery — все замечательно было, но ImageMagick есть не на всех хостингах :( так что убил потом всю идею…

Да, а в примере не хватает подложки для фоток — рамки как бы просвечиваются, и нижние три фото не «всплывают»
–1
FTM #
Самые нижние фото посмотреть нельзя, работает медленно. Уж лучше флэш, имхо.
+2
homm #
Нижние фотки нельзя посмотреть не потому, что что-то сделано не так, а потому что так задумано.
0
fatal #
Вот альтернативный способ — только HTML и CSS:
media.24ways.org/2009/14/5/index.html
Самые красивые эффекты на данный момент в Chrome 4 и Firefox 3.7a, но совсем скоро эта красота будет доступна и для Opera.
0
egorinsk #
Смотрел гугловские демки с крутящимися на SVG фотографиями — отвратительные тормоза. технологию считаю непригожнйо на сегодня. Кроме того, как я понимаю, яваскрипт при вставке картинки в SVG блокируется до ее полной загрузки.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.