От автора: всем, наверное, известно о новой, не кросбраузерной технологии canvas… C помощью этой технологии можно вытворять немыслимые вещи, например красиво отразить картинку.
Я изучаю эту технологию, но пока применять её рано, думаю как реализовать подобные эффекты, используя доступные инструменты каждому браузеру.
Что касается отражения картинки, мне это удалось.
Задача
Нам необходимо реализовать скрипт, который будет находить нужное нам изображение и вставлять в его родителя отражение, причём не просто такую же картинку, а с градиентной прозрачностью. Ну и понятное дело – картинка должна быть зеркальна по вертикали.
Таких картинок должно быть несколько.
Для красивости, мы ёщё и сделаем анимацию при наведении курсора. Картинка, при наведении, должна подскакивать, а отражение соответственно утопать и становится более прозрачным.
Метод
Файлы и вёрстка
Найдём, подберём изображения и вырежем для них превью.
Для работы скрипта, нужно создать несколько "img" картинок в виде превью, каждая из которых будет находиться в объекте с заданным классом. Например, в ссылке "a" с классом ".img".
Спозиционируем горизонтально и стилизуем наши ссылки с картинками.
Исходный план DOM
Javascript
Скрипт должен посчитать количество объектов с классом «img» и в соответствии с результатом запустить цикл добавления отражений.
Опираясь на порядковый номер объекта с классом «img», скрипт узнаёт ссылку на изображение по атрибуту src картинки внутри этого объекта, а также узнаёт его ширину и высоту. Вставляет в текущий объект с классом "img" div с классом "ref", сразу после картинки. Затем запускается цикл по вставке фрагмента в виде div, с шириной как у картинки высотой в 50 раз меньше чем у картинки. У созданного фрагмента задаётся фон по ссылке, полученной из src, и задвигается в зависимости от этапа цикла. Созданный div .ref отражается по вертикали.
План DOM результата работы скрипта
Анимация
При наведении курсора на изображение, скрипт сдвигает его вверх а его отражение вниз, делая его более прозрачным. При уходе курсора с изображения, скрипт возвращает всё в исходное положение.
Решение
Изображения
Для демонстрации я выбрал обои для рабочего стола на тему Ubuntu и сделал уменьшенные копии с высотой 100 пикселей.
HTML
Все картинки обязательно должны находиться в своём объекте с классом img. В моём случае это ссылка на большую картинку – оригинал.
Не забывайте присоединять файлы скриптов и стилей.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!-- начало документа --> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="//www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="description" content=""> <meta name="keywords" content=""> <link rel="SHORTCUT ICON" href="favicon.ico" type="image/x-icon" /> <!-- стили --> <link rel="stylesheet" href="css.css" type="text/css"/> <!-- jquery --> <script src="js/jquery.js" type="text/javascript"></script> <!-- наши скрипты --> <script src="js/js.js" type="text/javascript"></script> <title>Отражение изображения</title> </head> <body> <!-- произволное содержание страницы --> <div class="all" align="center"> <div class="head"> <h1> Отражение изображения с помощью jquery от Михаила Беляева.<br /> Специально для <a href="//webformyself.com">webformyself.com</a> </h1> </div> <!-- див с картинками --> <div class="gal"> <!-- ссылка > картинка класс "img" - обязательный --> <a href="img/1.jpg" class='img'><img src="img/mini/1.jpg" alt="ubuntu" /></a> <a href="img/2.jpg" class='img'><img src="img/mini/2.jpg" alt="ubuntu" /></a> <a href="img/3.jpg" class='img'><img src="img/mini/3.jpg" alt="ubuntu" /></a> <a href="img/4.jpg" class='img'><img src="img/mini/4.jpg" alt="ubuntu" /></a> <a href="img/5.jpg" class='img'><img src="img/mini/5.jpg" alt="ubuntu" /></a> </div> </div> </body> </html> |
CSS стили
Изучая стили, обратите внимание на позиционирование объектов.
Ещё вы заметите, что в описании стилей класса «img» указан нулевой размер шрифта, хотя мы ничего там писать и не собираемся. Смысл в том, что IE увеличивал заданную высоту фрагмента, до размера потенциального текста и отражение было по меньшей мере не красивым…
А эта строчка этот баг ликвидирует.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
/* убиваем отступы */ * { padding:0px; margin:0px; } /* произвольные стили */ h1 { font-size:25px; color:#3c3c3c; text-shadow:0px 1px 1px #dbdbdb; } h1 a { text-decoration:none; color:#3c3c3c; } h1 a:hover { color:#fff; text-shadow:0px 1px 1px #3c3c3c; } /* убиваем рамку картинок в ссылках для IE и FF */ a img { border:0px; } body { background:url(img/bg.png) repeat-x top; } /* общий див */ .all { width:100%; overflow:hidden; position:relative; } /* див с картинками */ .gal { margin-top:200px; width:960px; position:relative; } /* класс для ссылок или других объектов, содержащих изображения */ .img { position:relative; /* Задан размер шрифта - "0". Чтобы понять что это необходимо, я потратил целый день на борьбу с багом в IE. */ font-size:0px; margin-left:20px; background:url(img/imgshadow.png) no-repeat center center; float:left; z-index:100; } .img img { z-index:101; position:relative; } |
У нас получается вот такая картина:
Javascript
Вот момент создания объекта, ему присваиваются стили, обратите на них внимание.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
$(document).ready(function(){ /* ждём пока загрузится DOM Проверяем - сколько .img объектов выведено на странице и в соответствии с этой цифрой запускаем цикл обработки */ var imgcount = $('.img').size() - 1; for(var imgs = 0; imgs <= imgcount; imgs++) { $('.img:eq(' + imgs + ') img').bind('load', function(){ // ждём пока загрузится картинка, что бы с ней можно было работать var src = $(this).attr('src'); // узнаём сорс картинки var wi = $(this).width(); // выесняем ширену картинки var he = $(this).height(); // узнаём высоту картинки var count = 50; var forto = count - 1; var frag = he / count; // делим высоту на 50, чтобы получить высоту одного фрагмента картинки var ref = ""; // объявляем переменную, в которую будем заносить фрагменты $(this).parent().append("<div class='ref' style='width:" + wi + "; overflow:hidden;'></div>"); // вставляем в текущий объект .img див, сразу после картинки for(var i = 0; i <= forto; i++) // запускаем цикл составления фрагментов в переменной ref { var spr = frag * i; // здесь мы вычесляем на сколько сдвинуть фон фрагмента if(i < 10) { // у нормальных браузеров применяются различная от IE единица прозрачности var op = "0.0"+i; // если значение меньше 10, для нормальных браузеров используем сотые var opie = i; // а для IE челые } else { var op = "0."+i; // если значение больше 10, для нормальных браузеров используем десятые var opie = i; // а для IE челые } /* добавляем фрагмет к уже созданным */ ref = "<div style='background:url("+src+") no-repeat 0px -"+spr+"px;width:"+wi+"px;height:"+frag+"px;-webkit-transform:scale(1,-1);-moz-transform:scale(1,-1);-o-transform:scale(1,-1); filter:alpha(opacity=" + opie + ") flipv();opacity:"+op+";'></div>" + ref; } $(this).parent().children('.ref').append(ref); // вставляем созданные фрагменты в див .ref return false; }); } /* ну и анимируем всё это при наведении */ $('.img img').hover(function(){ $(this).stop().animate({'margin-top':'-20px'}, 300); // тянем картинку вверх $(this).parent().children('.ref').stop().animate({'margin-top':'40px','opacity':'0.5'}, 300); // отражение топим вниз и делаем прозрачнее }, function(){ $(this).stop().animate({'margin-top':'0px'}, 300); // на место $(this).parent().children('.ref').stop().animate({'margin-top':'0px','opacity':'1'}, 300); // обратно } ); }); |
Опа!
Результат:
Примечание
IE как всегда работает криво, на этот раз с событием "load()". Поэтому с локальных директорий вашего компьютера, скрипт работать не будет. Но в принципе это и не нужно, так как с сервера всё работает отлично.
Применяете и модернизируйте!
Ваши вопросы и отзывы жду в комментариях
С уважением Михаил Беляев.
Автор: Михаил Беляев.
Редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.
Комментарии (28)