- Главная»
- Уроки»
- HTML и DHTML»
- Зум слайдер
Зум слайдер
Сегодняшний черновик - это простой слайдер с возможностью раскрытия подробной информации о каждом элементе.
Для перемещения элементов мы используем CSS и dymanic.js.
Просим обратить внимание, что в данных демо используются современные CSS свойства, поэтому ожидаемы результаты будут видны только в последних версиях браузеров.
HTML
<!-- Main container --> <div class="container"> <!-- Blueprint header --> <header class="bp-header cf"> <!-- Page title etc. --> </header> <!-- Grid --> <section class="slider"> <div class="slide slide--current" data-content="content-1"> <div class="slide__mover"> <div class="zoomer flex-center"> <img class="zoomer__image" src="images/iphone.png" alt="iPhone" /> <div class="preview"> <img src="images/iphone-content-preview.png" alt="iPhone app preview" /> <div class="zoomer__area zoomer__area--size-2"></div> </div> </div> </div> <h2 class="slide__title"><span>The Classy</span> iPhone 6</h2> </div> <div class="slide" data-content="content-2"> <!-- ... --> </div> <!-- ... --> <nav class="slider__nav"> <button class="button button--nav-prev"> <i class="icon icon--arrow-left"></i> <span class="text-hidden">Previous product</span> </button> <button class="button button--zoom"> <i class="icon icon--zoom"></i> <span class="text-hidden">View details</span> </button> <button class="button button--nav-next"> <i class="icon icon--arrow-right"></i> <span class="text-hidden">Next product</span> </button> </nav> </section> <!-- /slider--> <!-- content --> <section class="content"> <div class="content__item" id="content-1"> <img class="content__item-img rounded-right" src="images/iphone-content.png" alt="Apple Watch Content" /> <div class="content__item-inner"> <h2>The iPhone 6</h2> <h3>Incredible performance for powerful apps</h3> <p>...</p> </div> </div> <div class="content__item" id="content-2"> <!-- ... --> </div> <!-- ... --> <button class="button button--close"> <i class="icon icon--circle-cross"></i> <span class="text-hidden">Close content</span> </button> </section> <!-- /content --> </div> <script src="js/classie.js"></script> <script src="js/dynamics.min.js"></script> <script src="js/main.js"></script>
CSS
/* Helper classes */ html, body { overflow: hidden; height: 100%; } .container { position: relative; overflow: hidden; overflow-y: scroll; width: 100%; height: 100%; -webkit-overflow-scrolling: touch; } .noscroll .container { overflow-y: hidden; } .slider { position: relative; z-index: 200; width: 100%; margin: 0 auto; padding: 0 0 7em; text-align: center; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-touch-callout: none; -khtml-user-select: none; } .slide { position: absolute; top: 0; visibility: hidden; width: 100%; opacity: 0; } .slide--current { position: relative; z-index: 100; visibility: visible; opacity: 1; } .slide__mover { position: relative; z-index: 100; } .slide__title { font-size: 1.75em; font-weight: normal; margin: 0 auto; padding: 1em 0 0 0; } .slide__title span { font-size: 55%; font-weight: bold; display: block; letter-spacing: 2px; text-transform: uppercase; color: #35303d; } .slider__nav { position: absolute; bottom: 2em; width: 100%; text-align: center; } .button { font-size: 1.31em; position: relative; display: inline-block; overflow: hidden; margin: 0 25px; padding: 0; cursor: pointer; color: #5c5edc; border: none; background: none; } .button:focus { outline: none; } .button:hover { color: #fff; } .text-hidden { position: absolute; top: 200%; } .button--close { font-size: 1.55em; position: absolute; top: 30px; right: 30px; margin: 0; opacity: 0; color: #50505a; -webkit-transition: opacity 0.3s; transition: opacity 0.3s; } .content--open .button--close { opacity: 1; } /* Zoomer */ .zoomer { position: relative; height: 360px; /* this is needed for IE10 so that vertical flexbox centering works */ } .flex-center { display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-align-items: center; -ms-flex-align: center; align-items: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } .zoomer__image { display: block; margin: 0; -webkit-flex: none; -ms-flex: none; flex: none; } .zoomer__area, .preview { position: absolute; top: 50%; left: 50%; -webkit-transform: translate3d(-50%,-50%,0); transform: translate3d(-50%,-50%,0); } .zoomer__area:focus { outline: none; } .zoomer__area--size-1 { /* Apple Watch */ width: 96px; height: 118px; } .zoomer__area--size-2 { /* iPhone */ width: 112px; height: 198px; } .zoomer__area--size-3 { /* MacBook */ width: 315px; height: 200px; } .zoomer__area--size-4 { /* iPad */ width: 150px; height: 200px; } .zoomer__area--size-5 { /* iMac */ width: 315px; height: 189px; } .preview { overflow: hidden; background: #18191b; } .preview img { display: block; border-radius: inherit; -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } .zoomer--active .preview img { -webkit-transform: translate3d(100%,0,0); transform: translate3d(100%,0,0); } .rounded { border-radius: 15px; } .rounded-right { border-radius: 0 15px 15px 0; } .preview__content { position: absolute; top: 0; left: 100%; width: 100%; height: 100%; border-radius: inherit; } /* Content */ .content { position: fixed; z-index: 1000; top: 0; left: -100%; overflow: hidden; overflow-y: scroll; width: 100%; height: 100vh; background: #18191b; -webkit-overflow-scrolling: touch; } .content--open { left: 0; } .content__item { position: absolute; top: 0; display: -webkit-flex; display: -ms-flexbox; display: flex; overflow: hidden; height: 0; min-height: 100%; margin: 0 auto; padding: 2em 0; pointer-events: none; opacity: 0; color: #fff; -webkit-align-items: center; -ms-flex-align: center; align-items: center; } .content__item--current { pointer-events: auto; opacity: 1; } .content__item--reset { height: auto; } .content h2 { font-size: 3.5em; font-weight: normal; margin: 0; } .content h3 { font-size: 1.95em; font-weight: normal; margin: 0.25em 0 0.5em; color: #685884; } .content p { font-size: 1.25em; line-height: 1.5; } .content__item-img { display: block; max-width: 40vw; max-height: 80vh; -webkit-transform: translate3d(-120%,0,0); transform: translate3d(-120%,0,0); -webkit-flex: none; -ms-flex: none; flex: none; } .content__item--current .content__item-img { -webkit-transform: translate3d(-10px,0,0); transform: translate3d(-10px,0,0); } .content__item-inner { padding: 0 10vw 0; opacity: 0; -webkit-transform: translate3d(0,50px,0); transform: translate3d(0,50px,0); } .content__item--current .content__item-inner { opacity: 1; -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } /**************************/ /* All synced transitions */ /**************************/ .zoomer { -webkit-transition: -webkit-transform 0.5s; transition: transform 0.5s; -webkit-transition-timing-function: cubic-bezier(0.7,0,0.3,1); transition-timing-function: cubic-bezier(0.7,0,0.3,1); } .zoomer.zoomer--notrans { -webkit-transition: none; transition: none; } .zoomer__image { -webkit-transition: opacity 0.3s 0.3s; transition: opacity 0.3s 0.3s; } .zoomer--active .zoomer__image { opacity: 0; -webkit-transition-delay: 0s; transition-delay: 0s; } .preview img { -webkit-transition: -webkit-transform 0.6s 0.3s; transition: transform 0.6s 0.3s; -webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1); transition-timing-function: cubic-bezier(0.2,1,0.3,1); } .zoomer--active .preview img { -webkit-transition: -webkit-transform 0.3s; transition: transform 0.3s; } .content { -webkit-transition: left 0s; transition: left 0s; } .content__item { -webkit-transition: opacity 0s; transition: opacity 0s; } .content, .content__item { /* delay for content to disappear and zoomer to start transitioning back to 0 */ -webkit-transition-delay: 0.3s; transition-delay: 0.3s; } .content--open, .content__item--current { -webkit-transition: none; transition: none; } .content__item-img { -webkit-transition: -webkit-transform 0.4s; transition: transform 0.4s; -webkit-transition-timing-function: cubic-bezier(0.7,1,0.8,1); transition-timing-function: cubic-bezier(0.7,1,0.8,1); } .content__item--current .content__item-img { -webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1); transition-timing-function: cubic-bezier(0.2,1,0.3,1); -webkit-transition-duration: 1s; transition-duration: 1s; } .content__item-inner { -webkit-transition: -webkit-transform 0.6s, opacity 0.3s; transition: transform 0.6s, opacity 0.3s; -webkit-transition-timing-function: cubic-bezier(0.7,1,0.8,1), ease; transition-timing-function: cubic-bezier(0.7,1,0.8,1), ease; } .content__item--current .content__item-inner { -webkit-transition-timing-function: cubic-bezier(0.2,1,0.3,1), ease; transition-timing-function: cubic-bezier(0.2,1,0.3,1), ease; -webkit-transition-duration: 1.7s; transition-duration: 1.7s; } /* Media Queries */ @media screen and (max-width: 50em) { .content__item { display: block; } .content__item-img { max-width: calc(100% - 80px); max-height: 70vh; } .content h2 { font-size: 3em; } .content__item-inner { font-size: 82%; padding: 4em 3em 2em; } }
JavaScript
/** * main.js * http://www.codrops.com * * Licensed under the MIT license. * http://www.opensource.org/licenses/mit-license.php * * Copyright 2015, Codrops * http://www.codrops.com */ ;(function(window) { 'use strict'; var bodyEl = document.body, docElem = window.document.documentElement, support = { transitions: Modernizr.csstransitions }, // transition end event name transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], onEndTransition = function( el, callback ) { var onEndCallbackFn = function( ev ) { if( support.transitions ) { if( ev.target != this ) return; this.removeEventListener( transEndEventName, onEndCallbackFn ); } if( callback && typeof callback === 'function' ) { callback.call(this); } }; if( support.transitions ) { el.addEventListener( transEndEventName, onEndCallbackFn ); } else { onEndCallbackFn(); } }, // window sizes win = {width: window.innerWidth, height: window.innerHeight}, // some helper vars to disallow scrolling lockScroll = false, xscroll, yscroll, scrollContainer = document.querySelector('.container'), // the main slider and its items sliderEl = document.querySelector('.slider'), items = [].slice.call(sliderEl.querySelectorAll('.slide')), // total number of items itemsTotal = items.length, // navigation controls/arrows navRightCtrl = sliderEl.querySelector('.button--nav-next'), navLeftCtrl = sliderEl.querySelector('.button--nav-prev'), zoomCtrl = sliderEl.querySelector('.button--zoom'), // the main content element contentEl = document.querySelector('.content'), // close content control closeContentCtrl = contentEl.querySelector('button.button--close'), // index of current item current = 0, // check if an item is "open" isOpen = false, isFirefox = typeof InstallTrigger !== 'undefined', // scale body when zooming into the items, if not Firefox (the performance in Firefox is not very good) bodyScale = isFirefox ? false : 3; // some helper functions: function scrollX() { return window.pageXOffset || docElem.scrollLeft; } function scrollY() { return window.pageYOffset || docElem.scrollTop; } // from http://www.sberry.me/articles/javascript-event-throttling-debouncing function throttle(fn, delay) { var allowSample = true; return function(e) { if (allowSample) { allowSample = false; setTimeout(function() { allowSample = true; }, delay); fn(e); } }; } function init() { initEvents(); } // event binding function initEvents() { // open items zoomCtrl.addEventListener('click', function() { openItem(items[current]); }); // close content closeContentCtrl.addEventListener('click', closeContent); // navigation navRightCtrl.addEventListener('click', function() { navigate('right'); }); navLeftCtrl.addEventListener('click', function() { navigate('left'); }); // window resize window.addEventListener('resize', throttle(function(ev) { // reset window sizes win = {width: window.innerWidth, height: window.innerHeight}; // reset transforms for the items (slider items) items.forEach(function(item, pos) { if( pos === current ) return; var el = item.querySelector('.slide__mover'); dynamics.css(el, { translateX: el.offsetWidth }); }); }, 10)); // keyboard navigation events document.addEventListener( 'keydown', function( ev ) { if( isOpen ) return; var keyCode = ev.keyCode || ev.which; switch (keyCode) { case 37: navigate('left'); break; case 39: navigate('right'); break; } } ); } // opens one item function openItem(item) { if( isOpen ) return; isOpen = true; // the element that will be transformed var zoomer = item.querySelector('.zoomer'); // slide screen preview classie.add(zoomer, 'zoomer--active'); // disallow scroll scrollContainer.addEventListener('scroll', noscroll); // apply transforms applyTransforms(zoomer); // also scale the body so it looks the camera moves to the item. if( bodyScale ) { dynamics.animate(bodyEl, { scale: bodyScale }, { type: dynamics.easeInOut, duration: 500 }); } // after the transition is finished: onEndTransition(zoomer, function() { // reset body transform if( bodyScale ) { dynamics.stop(bodyEl); dynamics.css(bodyEl, { scale: 1 }); // fix for safari (allowing fixed children to keep position) bodyEl.style.WebkitTransform = 'none'; bodyEl.style.transform = 'none'; } // no scrolling classie.add(bodyEl, 'noscroll'); classie.add(contentEl, 'content--open'); var contentItem = document.getElementById(item.getAttribute('data-content')) classie.add(contentItem, 'content__item--current'); classie.add(contentItem, 'content__item--reset'); // reset zoomer transform - back to its original position/transform without a transition classie.add(zoomer, 'zoomer--notrans'); zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)'; zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)'; }); } // closes the item/content function closeContent() { var contentItem = contentEl.querySelector('.content__item--current'), zoomer = items[current].querySelector('.zoomer'); classie.remove(contentEl, 'content--open'); classie.remove(contentItem, 'content__item--current'); classie.remove(bodyEl, 'noscroll'); if( bodyScale ) { // reset fix for safari (allowing fixed children to keep position) bodyEl.style.WebkitTransform = ''; bodyEl.style.transform = ''; } /* fix for safari flickering */ var nobodyscale = true; applyTransforms(zoomer, nobodyscale); /* fix for safari flickering */ // wait for the inner content to finish the transition onEndTransition(contentItem, function(ev) { classie.remove(this, 'content__item--reset'); // reset scrolling permission lockScroll = false; scrollContainer.removeEventListener('scroll', noscroll); /* fix for safari flickering */ zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)'; zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)'; /* fix for safari flickering */ // scale up - behind the scenes - the item again (without transition) applyTransforms(zoomer); // animate/scale down the item setTimeout(function() { classie.remove(zoomer, 'zoomer--notrans'); classie.remove(zoomer, 'zoomer--active'); zoomer.style.WebkitTransform = 'translate3d(0,0,0) scale3d(1,1,1)'; zoomer.style.transform = 'translate3d(0,0,0) scale3d(1,1,1)'; }, 25); if( bodyScale ) { dynamics.css(bodyEl, { scale: bodyScale }); dynamics.animate(bodyEl, { scale: 1 }, { type: dynamics.easeInOut, duration: 500 }); } isOpen = false; }); } // applies the necessary transform value to scale the item up function applyTransforms(el, nobodyscale) { // zoomer area and scale value var zoomerArea = el.querySelector('.zoomer__area'), zoomerAreaSize = {width: zoomerArea.offsetWidth, height: zoomerArea.offsetHeight}, zoomerOffset = zoomerArea.getBoundingClientRect(), scaleVal = zoomerAreaSize.width/zoomerAreaSize.height < win.width/win.height ? win.width/zoomerAreaSize.width : win.height/zoomerAreaSize.height; if( bodyScale && !nobodyscale ) { scaleVal /= bodyScale; } // apply transform el.style.WebkitTransform = 'translate3d(' + Number(win.width/2 - (zoomerOffset.left+zoomerAreaSize.width/2)) + 'px,' + Number(win.height/2 - (zoomerOffset.top+zoomerAreaSize.height/2)) + 'px,0) scale3d(' + scaleVal + ',' + scaleVal + ',1)'; el.style.transform = 'translate3d(' + Number(win.width/2 - (zoomerOffset.left+zoomerAreaSize.width/2)) + 'px,' + Number(win.height/2 - (zoomerOffset.top+zoomerAreaSize.height/2)) + 'px,0) scale3d(' + scaleVal + ',' + scaleVal + ',1)'; } // navigate the slider function navigate(dir) { var itemCurrent = items[current], currentEl = itemCurrent.querySelector('.slide__mover'), currentTitleEl = itemCurrent.querySelector('.slide__title'); // update new current value if( dir === 'right' ) { current = current < itemsTotal-1 ? current + 1 : 0; } else { current = current > 0 ? current - 1 : itemsTotal-1; } var itemNext = items[current], nextEl = itemNext.querySelector('.slide__mover'), nextTitleEl = itemNext.querySelector('.slide__title'); // animate the current element out dynamics.animate(currentEl, { opacity: 0, translateX: dir === 'right' ? -1*currentEl.offsetWidth/2 : currentEl.offsetWidth/2, rotateZ: dir === 'right' ? -10 : 10 }, { type: dynamics.spring, duration: 2000, friction: 600, complete: function() { dynamics.css(itemCurrent, { opacity: 0, visibility: 'hidden' }); } }); // animate the current title out dynamics.animate(currentTitleEl, { translateX: dir === 'right' ? -250 : 250, opacity: 0 }, { type: dynamics.bezier, points: [{"x":0,"y":0,"cp":[{"x":0.2,"y":1}]},{"x":1,"y":1,"cp":[{"x":0.3,"y":1}]}], duration: 450 }); // set the right properties for the next element to come in dynamics.css(itemNext, { opacity: 1, visibility: 'visible' }); dynamics.css(nextEl, { opacity: 0, translateX: dir === 'right' ? nextEl.offsetWidth/2 : -1*nextEl.offsetWidth/2, rotateZ: dir === 'right' ? 10 : -10 }); // animate the next element in dynamics.animate(nextEl, { opacity: 1, translateX: 0 }, { type: dynamics.spring, duration: 2000, friction: 600, complete: function() { items.forEach(function(item) { classie.remove(item, 'slide--current'); }); classie.add(itemNext, 'slide--current'); } }); // set the right properties for the next title to come in dynamics.css(nextTitleEl, { translateX: dir === 'right' ? 250 : -250, opacity: 0 }); // animate the next title in dynamics.animate(nextTitleEl, { translateX: 0, opacity: 1 }, { type: dynamics.bezier, points: [{"x":0,"y":0,"cp":[{"x":0.2,"y":1}]},{"x":1,"y":1,"cp":[{"x":0.3,"y":1}]}], duration: 650 }); } // disallow scrolling (on the scrollContainer) function noscroll() { if(!lockScroll) { lockScroll = true; xscroll = scrollContainer.scrollLeft; yscroll = scrollContainer.scrollTop; } scrollContainer.scrollTop = yscroll; scrollContainer.scrollLeft = xscroll; } init(); })(window);
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://tympanus.net/codrops/2015/07/06/zoom-slider/
Перевел: Станислав Протасевич
Урок создан: 6 Июля 2015
Просмотров: 20326
Правила перепечатки
5 последних уроков рубрики "HTML и DHTML"
-
Лайфхак: наиполезнейшая функция var_export()
При написании или отладки PHP скриптов мы частенько пользуемся функциями var_dump() и print_r() для вывода предварительных данных массив и объектов. В этом посте я бы хотел рассказать вам о функции var_export(), которая может преобразовать массив в формат, пригодный для PHP кода.
-
17 бесплатных шаблонов админок
Парочка бесплатных шаблонов панелей администрирования.
-
30 сайтов для скачки бесплатных шаблонов почтовых писем
Создание шаблона для письма не такое уж простое дело. Предлагаем вам подборку из 30 сайтов, где можно бесплатно скачать подобные шаблоны на любой вкус.
-
Как осуществить задержку при нажатии клавиши с помощью jQuery?
К примеру у вас есть поле поиска, которое обрабатывается при каждом нажатии клавиши клавиатуры. Если кто-то захочет написать слово Windows, AJAX запрос будет отправлен по следующим фрагментам: W, Wi, Win, Wind, Windo, Window, Windows. Проблема?.
-
15 новых сайтов для скачивания бесплатных фото
Подборка из 15 новых сайтов, где можно скачать бесплатные фотографии для заполнения своих сайтов.