Отражение изображения с помощью jQuery

отражение изображений

От автора: всем, наверное, известно о новой, не кросбраузерной технологии canvas… C помощью этой технологии можно вытворять немыслимые вещи, например красиво отразить картинку.
Я изучаю эту технологию, но пока применять её рано, думаю как реализовать подобные эффекты, используя доступные инструменты каждому браузеру.

Что касается отражения картинки, мне это удалось.

результат

скачать исходникидемо

Задача

Нам необходимо реализовать скрипт, который будет находить нужное нам изображение и вставлять в его родителя отражение, причём не просто такую же картинку, а с градиентной прозрачностью. Ну и понятное дело – картинка должна быть зеркальна по вертикали.

Таких картинок должно быть несколько.

Для красивости, мы ёщё и сделаем анимацию при наведении курсора. Картинка, при наведении, должна подскакивать, а отражение соответственно утопать и становится более прозрачным.

Метод

Файлы и вёрстка

Найдём, подберём изображения и вырежем для них превью.

Для работы скрипта, нужно создать несколько "img" картинок в виде превью, каждая из которых будет находиться в объекте с заданным классом. Например, в ссылке "a" с классом ".img".

Спозиционируем горизонтально и стилизуем наши ссылки с картинками.

Исходный план DOM

исходный план DOM

Javascript

Скрипт должен посчитать количество объектов с классом «img» и в соответствии с результатом запустить цикл добавления отражений.

Опираясь на порядковый номер объекта с классом «img», скрипт узнаёт ссылку на изображение по атрибуту src картинки внутри этого объекта, а также узнаёт его ширину и высоту. Вставляет в текущий объект с классом "img" div с классом "ref", сразу после картинки. Затем запускается цикл по вставке фрагмента в виде div, с шириной как у картинки высотой в 50 раз меньше чем у картинки. У созданного фрагмента задаётся фон по ссылке, полученной из src, и задвигается в зависимости от этапа цикла. Созданный div .ref отражается по вертикали.

План DOM результата работы скрипта

план DOM

Анимация

При наведении курсора на изображение, скрипт сдвигает его вверх а его отражение вниз, делая его более прозрачным. При уходе курсора с изображения, скрипт возвращает всё в исходное положение.

Решение

Изображения

Для демонстрации я выбрал обои для рабочего стола на тему Ubuntu и сделал уменьшенные копии с высотой 100 пикселей.

HTML

Все картинки обязательно должны находиться в своём объекте с классом img. В моём случае это ссылка на большую картинку – оригинал.

Не забывайте присоединять файлы скриптов и стилей.

<!-- начало документа -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://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="http://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 увеличивал заданную высоту фрагмента, до размера потенциального текста и отражение было по меньшей мере не красивым…

А эта строчка этот баг ликвидирует.

/*
убиваем отступы
*/
*
{
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

Вот момент создания объекта, ему присваиваются стили, обратите на них внимание.

$(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.

JavaScript&jQuery с нуля до профи

Пройдите пошаговый видеокурс по JavaScript&jQuery

Научиться

Метки:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (28)

  1. Игорь

    Классно!
    Очень красиво!

  2. Елена

    Все очень интересно, но не для профессионала все-таки сложно, хотя я попыталась все-таки…
    А вы молодцы, не останавливайтесь на достигнутом. А я — только учусь… Но все ваши рассылки — просматриваю и хочу научиться применять для чего создала свой сайт тоже

  3. Эдуард

    Спасибо за статью!
    Рисовал отражения в фотошопе, потом анимировал.
    Так, как у Вас в статье, пожалуй поуниверсальнее будет!
    Ещё раз спасибо!

  4. Виктор

    Беляеву большой респект! И вообще. Недавно набрел на ваш сайт. Здесь столько интересного! Спасибо! Читать и читать. Чем и занимаюсь.

  5. Юрий

    очень красиво. Спасибо за материал.

  6. Виктория

    Блестяще! Как всегда в вашей рубрике. Большое спасибо. Обязательно посоветую друзьям.

  7. Артур

    Очень красиво. Не очень сложно. Догадаться до этого могут только профессионалы!:)

  8. Александр Новиков

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

  9. Андрей

    Все это хорошо, но опять же увеличивает загрузку страницы (скорость). Эффект конечно красивый. Спасибо.

  10. Сергей

    Cпасибо, ребята!
    Уже не первый раз пользуюсь Вашими решениями и все прекрасно!

  11. Pocherk

    Неплохо! Но мне больше нравится решение для зеркального изображения с помощью скрипта Reflection.js Почитать о нем можете по адресу
    aka-edd.ru/index.php?newsid=65 и никаких заморочек с IE

  12. Юрий

    А у меня только картинки вверх подпрыгивают — никакого отражения нет.

  13. Денис

    Как по мне, бесполезная штука. Только пожирает место на странице.
    А так ок, только вместо кучи переменных ассоциативный массив и ref = «» + ref;

    ЗАМЕНИТЬ НА ДРУГОЕ, на более низкоуровневую писанину, типа приминить класс такой то и т.д.

  14. Виталий

    Уважаемый автор, такое впечатление, что вы оторваны от действительности. Я — любитель и подписался на ваши новости и уроки, чтобы получать доступную информацию и уроки, а не эти сплошные тэги для профессионалов. Будьте проще и к вам потянутся. А пока мне ни один ваш урок не пригодился.

    • Виктор Рог

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

    • Pocherk

      Виталий, не правы! Автор как раз в курсе современных трендов web-строительства и ему респект и уважуха за его уроки, а если вы не все понимаете, то читайте материалы для новичков.

      • Владислав

        Абсолютно с вами согласен, если что-то не понимаеш, так возьми материал для начинающих и постепенно разберёшся,а познать всё и сразу не возможно.А на этом сайте информация подается наилучшим образом, всё очень легко воспринимается, респект!!!

    • Александр

      Виталий! Я сам любитель и не проф в сайтостроении, но если бы такие уроки были лет 10 назад (когда я начинал), то и мои сайты были бы на порядок круче. Теперь я это исправляю. А авторам большое спасибо!

  15. mike

    Вообще я ASP.Net-чик но Ваш сайт это бомба.
    Идеи почерпнутые здесь бесценны!
    Спасибо разработчикам этого сайта.

  16. Elena

    интересно, да…
    но пока не знаю — как можно применить…

  17. Гульсина

    Пока в разработке сайт но скоро покажу и выложу ! А картинки эти с Kubunty и зеркальное отражение и кубическое,трапециевидное Ромбовое и даже с падающим дождём и снегом всё легко! :)

  18. Евгений

    Я абсолютный новичек в этом деле, однако читая материалы этого ресурса, пробуя его инструменты, понимаю, что авторы действительно преподают дельную информацию, которая позволяет даже неспециалисту потихоньку «вливаться» в тему сайтостроения. Огромное уважение!!!! Спасибо!!!

  19. Сергей

    Добрый день.
    Спасибо за ваши многочисленные уроки, правда использую не многие т.к. строю сайты в основном на движке Джумла и пользую готовые компоненты и плагины.
    Просматривая вашу демо страницу в мозиле по данному уроку, я увидел следующий «глюк». При клике на фото — оно открывается в новом окне и в полном размере, а при нажатии в браузере «назад», попадаешь на начальную страницу, но все фото при этом уже без отражений. И отражения появляются только после перезагрузки. Это недоработки или так и должно работать?
    Спасибо.

  20. БЛОGГЕР

    Мне очень понравилось. Как бы это в Blogspot реализовать…

  21. Эдуард

    А как-бы такую-же штуку с текстом провернуть?

    • Михаил

      По сути по такому же принципу, только не получится реализовать переменную прозрачность.
      Написать скрипт, который будет добавлять копию блока, только вертикально отражённую.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree