В статье описано, как с использованием jQuery создать 3D эффекты CSS при наведении курсора.



Тут можно Посмотреть, а тут — Скачать

В примерах ниже используются миниатюры, которые при наведении курсора будут отображать определенную информацию CSS. Благодаря jQuery при наведении на изображения, они появляться в свернутом или согнутом виде. Для этих эффектов будет использоваться CSS 3D transforms.

Разметка в HTML


Такой будет разметка для уменьшенной структуры:

<div id="grid" class="main">
 
	<div class="view">

		<div class="view-back">
			<span data-icon="A">566</span>
			<span data-icon="B">124</span>
			<a href="http://www.flickr.com/photos/ag2r/5439506585/in/photostream">></a>
		</div>

		<img src="images/1.jpg" />

	</div>

	<div class="view">

	<!-- ... -->

	</div>

	<!-- ... -->
	
</div>


Каждая миниатюра находится в контейнере. Нужно создать структуру для каждого раздела с контейнера view, используя JavaScript:

<div class="view">

	<div class="view-back">
		<!-- ... -->
	</div>
	
	<div class="slice s1" style="background-image: url(images/1.jpg); ">
		<span class="overlay"></span>
		
		<div class="slice s2" style="background-image: url(images/1.jpg); ">
			<span class="overlay"></span>
			
			<div class="slice s3" style="background-image: url(images/1.jpg); ">
				<span class="overlay"></span>
				
				<div class="slice s4" style="background-image: url(images/1.jpg); ">
					<span class="overlay"></span>
					
					<div class="slice s5" style="background-image: url(images/1.jpg); ">
						<span class="overlay"></span>
					</div><!-- /s5 -->
				
				</div><!-- /s4 -->
					
			</div><!-- /s3 -->
				
		</div><!-- /s2 -->
			
	</div><!-- /s1 -->
	
</div><!-- /view -->


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

Функция JavaScript будет выглядеть так:

$.fn.hoverfold = function( args ) {

	this.each( function() {
	
		$( this ).children( '.view' ).each( function() {
		
			var $item 	= $( this ),
				img		= $item.children( 'img' ).attr( 'src' ),
				struct	= '<div class="slice s1">';
					struct	+='<div class="slice s2">';
						struct	+='<div class="slice s3">';
							struct	+='<div class="slice s4">';
								struct	+='<div class="slice s5">';
								struct	+='</div>';
							struct	+='</div>';
						struct	+='</div>';
					struct	+='</div>';
				struct	+='</div>';
				
			var $struct = $( struct );
			
			$item.find( 'img' ).remove().end().append( $struct ).find( 'div.slice' ).css( 'background-image', 'url(' + img + ')' ).prepend( $( '<span class="overlay" ></span>' ) );
			
		} );
		
	});

};


Теперь переходим к настройке общих стилей.

CSS


Определяем стиль для контейнера с миниатюрами и добавляем перспективу:

.view {
	width: 316px;
	height: 216px;
	margin: 10px;
	float: left;
	position: relative;
	border: 8px solid #fff;
	box-shadow: 1px 1px 2px rgba(0,0,0,0.05);
	background: #333;
	perspective: 500px;
}


Некоторым частям добавим 3D transitions:


.view .slice{
	width: 60px;
	height: 100%;
	z-index: 100;
	transform-style: preserve-3d;
	transform-origin: left center;
	transition: transform 150ms ease-in-out;
	
}


Часть описания, которое открывается при сдвиге изображения, будет имеет следующий стиль:

.view div.view-back{
	width: 50%;
	height: 100%;
	position: absolute;
	right: 0;
	background: #666;
	z-index: 0;
}


Элементы span и ссылки:

.view-back span {
	display: block;
	float: right;
	padding: 5px 20px 5px;
	width: 100%;
	text-align: right;
	font-size: 16px;
	color: rgba(255,255,255,0.6);
}

.view-back span:first-child {
	padding-top: 20px;
}

.view-back a {
	display: bock;
	font-size: 18px;
	color: rgba(255,255,255,0.4);
	position: absolute;
	right: 15px;
	bottom: 15px;
	border: 2px solid rgba(255,255,255,0.3);
	border-radius: 50%;
	width: 30px;
	height: 30px;
	line-height: 22px;
	text-align: center;
	font-weight: 700;
}

.view-back a:hover {
	color: #fff;
	border-color: #fff;
}


Для иконки перед элементами span используется шрифт Fontello. Прежде чем добавить атрибут data-icon в span, для вывода используем псевдо-класс :before

.view-back span[data-icon]:before {
    content: attr(data-icon);
    font-family: 'icons';
    color: #aaa;
	color: rgba(255,255,255,0.2);
	text-shadow: 0 0 1px rgba(255,255,255,0.2);
	padding-right: 5px;
}


Все, кроме первой части, должно сдвинуться вправо (вспоминаем про вложенную структуру):

.view .s2, 
.view .s3, 
.view .s4, 
.view .s5 {
	transform: translateX(60px);
}


Далее устанавливаем соответствующие позиции background для каждой части фонового изображения:

.view .s1 {
	background-position: 0px 0px;
}
.view .s2 {
	background-position: -60px 0px;
}
.view .s3 {
	background-position: -120px 0px;
}
.view .s4 {
	background-position: -180px 0px;
}
.view .s5 {
	background-position: -240px 0px;
}


В overlays по умолчанию будет непрозрачность 0. Добавляем переход и меняем уровень непрозрачности CSS при наведении:

.view .overlay {
	width: 60px;
	height: 100%;
	opacity: 0;
	position: absolute;
	transition: opacity 150ms ease-in-out;
}

.view:hover .overlay {
	opacity: 1;
}


Зафиксируем позицию и добавим z-index для изображения. Также добавим переход для браузеров, которые не поддерживают 3D преобразования:

.view img {
	position: absolute;
	z-index: 0;
	transition: left 0.3s ease-in-out;
}


В случае, если браузер не поддерживает 3D свойства, следует загрузить дополнительную таблицу стилей fallback.css, со следующим содержанием:


.view {
	overflow: hidden;
}

.view:hover img {
	left: -85px;
}

.view div.view-back {
	background: #666;
}


Это заставит изображение перемещаться влево при наведении курсора. Посмотрим на примере.

Пример


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


.view {
	perspective: 1050px;
}

.view div {
	transition: all 0.3s ease-in-out;
}


Вторая, третья, четвертая и пятая части будут передвинуты и повернуты в 3D, создавая эффект сгиба:

.view:hover .s2{
	transform: translate3d(59px,0,0) rotate3d(0,1,0,-45deg);
}
.view:hover .s3, 
.view:hover .s5{
	transform: translate3d(59px,0,0) rotate3d(0,1,0,90deg);
}
.view:hover .s4{
	transform: translate3d(59px,0,0) rotate3d(0,1,0,-90deg);
}


Добавляем градиенты в overlays для большей реалистичности:

.view .s2 > .overlay {
	background: linear-gradient(right, rgba(0,0,0,0.05) 0%,rgba(0,0,0,0) 100%);
}

.view .s3 > .overlay {
	background: linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255, 255, 255, 0.2) 100%);
}

.view .s4 > .overlay {
	background: linear-gradient(right, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.2) 100%);
}

.view .s5 > .overlay {
	background: linear-gradient(left, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 100%);
}


В некоторых деталях миниатюры при наведении также будет присутсвовать фоновый градиент CSS (для моделирования тени от изображений):


.view div.view-back{
	background: linear-gradient(left, #0a0a0a 0%,#666666 100%);
}


Изображения предоставлены Angelo Gonzalez, с соответствующей лицензией Creative Commons Attribution 2.0 Generic (CC BY 2.0) License.

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


  1. psman
    14.04.2016 18:24
    +7

    Перевод статьи 2012 года…


    1. myrrec
      14.04.2016 19:05
      +3

      Возраст не имеет никакой разницы — почему бы и не посмотреть статью 2012 года, если она хорошая?


      1. psman
        14.04.2016 19:11

        Статья оригинальная на блоге который уже переводили без разрешения авторов. В целом уже в закладках и так же как и http://tympanus.net/codrops/category/tutorials/ в подписках у всех кто хоть как то верстает или следит за вебом.


      1. Rad1calDreamer
        15.04.2016 19:15
        +2

        На tympanus всегда хорошие статьи. Почему, если уж и переводить, то не взять свежие?


    1. JCHouse
      15.04.2016 11:36

      А я зашел почитать, потому что словил себя на том что не писал на джиквери 4 года! И вот на тебе как раз 2012 год :)


  1. krosaff4ik
    14.04.2016 18:38
    -1

    Круто конечно, но не знаю как вы, а я бы с удовольствием забыл про всякие веб GL и CSS 3 за возврат разницы в 1-2 гб ОЗУ.


    1. gorodnev
      15.04.2016 19:20

      Нет, от CSS3 точно не стоит отказываться. Добиваться одинаковой отрисовки для разных браузеров и устройств только browser-specific селекторами и свойствами — это боль и унижение.


      1. RedCatX
        17.04.2016 00:07

        Может тогда хотя бы откажетесь от тяжёлых CSS и JS фреймворков, и будете создавать страницы по старинке, с ручной оптимизацией? Ведь открывать тяжёлые тормозящие сайты — это тоже боль и унижение.


  1. Fen1kz
    14.04.2016 18:56
    +5

    Я думал вы "крутые эффекты" на jQuery уже вымерли.


    1. Ashot
      14.04.2016 19:02

      Да jQuery-то ту по большому счёту не при чём: эта функция всего лишь создаёт структуру «слайсов» из картинки. Эти слайсы можно было бы и в ручную сверстать, и на pure js написать такую же функцию. Просто на jquery для демки-то это быстрее сделать.


  1. seokirill
    14.04.2016 20:29

    ничего не хочу сказать, но тут настолько банально, нет какого-то раскрытого тайного знания, чего я всегда жду от хабра(


    1. ShNURoK42
      14.04.2016 21:35
      +3

      Может перестать ждать и начать жить?


    1. Barafu
      14.04.2016 22:36

      Здесь, в общем-то, раскрывается тайное знание о том, почему блуждание по вебу скоро будет требовать таких же вложений в клиентскую машину, как и игры.
      У меня на Haswell и 18Гб оперативки тормозят почти все примеры с этого сайта.


      1. seokirill
        14.04.2016 22:42

        мак? Уменя даже на телефоне не тормозит


        1. SerDIDG
          15.04.2016 06:34

          А почему на маке должно тормозить? Всё нормально работает (Air 2014).


          1. seokirill
            15.04.2016 08:27

            Haswell и 18Гб

            Я просто подумал, что у дядьки мак.
            Haswell-камни с 13 года на pro ставят.


        1. Barafu
          15.04.2016 13:21

          Нет, просто Firefox как и у половины населения интернета.


          1. seokirill
            15.04.2016 13:46

            За что все его любят, если он очевидно крайне медлителен?


  1. Athari
    15.04.2016 06:33
    +1

    Adding some perspective with CSS3 and jQuery — best viewed in WebKit browsers

    Этот срам убрать пора. Во-первых, все браузеры умеют. Во-вторых, Хром единственный не справился с плавным включением тени.


  1. skoder
    15.04.2016 06:54
    +3

    Вопрос только — зачем тут jQuery, да еще и в заголовке

    function hoverfold() {
        'use strict';
        [].slice.call(document.querySelectorAll('.view')).forEach(function (elm) {
            var img = elm.getElementsByTagName('img')[0],
                src = img.getAttribute('src'),
                div = document.createElement('div'),
                overlay = document.createElement('span'),
                struct = '<div class="slice s1">' +
                    '<div class="slice s2">' +
                        '<div class="slice s3">' +
                            '<div class="slice s4">' +
                                '<div class="slice s5">' +
                                '</div>' +
                            '</div>' +
                        '</div>' +
                    '</div>' +
                '</div>';
            div.innerHTML = struct;
            struct = div.firstChild;
            overlay.className = 'overlay';
    
            img.parentNode.insertBefore(struct, img);
            img.parentNode.removeChild(img);
    
            do {
                struct.style.backgroundImage = 'url(' + src + ')';
                struct.parentNode.insertBefore(overlay.cloneNode(), struct);
                struct = struct.firstChild;
            } while (struct);
        });
    }