Слайд-шоу - 3D-куб
Добавить в избранное
В этом слайд-шоу изображения вращаются в сногсшибательном 3D-стиле, никаких специальных очков не требуется! Он использует преобразование CSS3 для размещения двух панелей в трехмерном пространстве рядом и перпендикулярно друг другу, создавая иллюзию куба. Эффект куба работает в IE10+ и во всех современных версиях Firefox и Chrome, в том числе на мобильных устройствах. Браузеры, которые не поддерживают эффект куба, просто получат обычное слайд-шоу без эффектов.
По слайд-шоу можно перемещаться либо вручную, создавая кнопки «вперед» и «назад», либо проводя пальцем по экрану на мобильных устройствах. Его также можно настроить на автоматический поворот либо только в ручную, плюс каждый слайд может быть дополнительно снабжен гиперссылкой.
Можете с капировать скрипт или скачать его.
index.html:
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Слайд-шоу - 3D-куб</title>
<style>
body {
background-color: black;
}
div.jkcubeslideshow {
/* основной контейнер */
background: black;
display: block;
width: 300px; /* ширина основного контейнера по умолчанию */
height: 575px; /* высота основного контейнера по умолчанию */
position: relative;
-webkit-perspective: 1000px; /* Чем больше значение, тем менее выражен 3D-эффект */
perspective: 1000px; /* Чем больше значение, тем менее выражен 3D-эффект */
margin: 0 auto;
}
div.side1, div.side2 {
/* две панели, образующие эффект куба */
width: 100%;
height: 100%;
position: absolute;
-moz-box-sizing: border-box;
box-sizing: border-box;
backface-visibility: hidden; /* скрыть обратную сторону DIV */
transition: all 1s ease-in-out; /* CSS-переход. Фактическая продолжительность, установленная сценарием */;
}
div.side1 img, div.side2 img {
/* как должны быть размеры изображений слайд-шоу внутри панелей? */
width: 100%;
height: 500px;
}
/* стрелки */
.arrows {
display: flex;
justify-content: space-between;
align-items: center;
width: 300px;
height: 30px;
margin: 0 auto;
position: absolute;
left: 0;
right: 0;
bottom: 5px;
top: 490px;
}
.str {
width: 20px;
margin: 3px;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jkcubeslideshow.js"></script>
<script>
var cubeshowvar1 // произвольная, но уникальная переменная для хранения экземпляра слайд-шоу
jQuery(function($){
cubeshowvar1 = new jkcubeslideshow({
id: 'cubeshow1',
dimensions: [300, 375],
images: [
['food1.jpg'],
['food2.jpg'],
['food3.jpg'],
['food4.jpg'],
['food5.jpg'] // без запятой после последней картинки
] // без запятой после последнего параметра
})
})
</script>
</head>
<body>
<div class="jkcubeslideshow" id="cubeshow1">
</div>
<br>
<div class="arrows">
<a href="#" onClick="cubeshowvar1.rotatecube('back'); return false"> <img src="blueleft.png" class="str" style="border:none" /></a> <a href="#" onClick="cubeshowvar1.rotatecube('forward'); return false" style="margin-left:160px"><img src="blueright.png" class="str" style="border:none" /></a>
</div>
</body>
</html>
jkcubeslideshow.js:
var defaults = {
slideshowmarkup: '<div><div class="side1"></div><div class="side2"></div></div></div>',
pause: 3000, // если поставите 0, то будет вращаться только в ручную
fxduration: 1000,
desc: [],
swipethreshold: [50, 300], // расстояние, пройденное в течение x миллисекунд, прежде чем это будет считаться пролистыванием [пиксели, миллисекунды]
linktarget: '_new'
}
var transform3d = typeof $(document.documentElement).css('perspective') != "undefined" // тест на поддержку 3D-преобразования
function setslidehtml(el, html, options){
var slidehtml = ''
if (el[1])
slidehtml += '<a href="' + el[1] + '" target="' + options.linktarget + '">'
slidehtml += '<img src="' + el[0] + '"/>'
if (el[1])
slidehtml +='</a>'
slidehtml += html? '<br/>' + html : ''
return slidehtml
}
function constructTransform(deg, x, y, z){
return 'rotateY(' + deg + 'deg) translate3D(' + x + 'px,' + y + 'px,' + z + 'px)'
}
window.jkcubeslideshow = function(settings){
var thisinst = this
var s = $.extend({}, defaults, settings)
var transitionendCount = 0
var transitioninProgress = false
var preloadimages = []
var curimage = 0
var pausetimer = null
var totalimages = s.images.length
var $maincontainer = $('#' + s.id)
if (s.dimensions && s.dimensions[0])
$maincontainer.css({width: s.dimensions[0], height: s.dimensions[1]})
var containerwidth = $maincontainer.width()
$maincontainer.html(s.slideshowmarkup) // заполнить пустой основной контейнер разметкой каркасного куба
var mousemoveevtstr = 'mousemove.dragstart' + s.id + ' touchmove.dragstart' + s.id
var mouseupevtstr= 'mouseup.dragend' + s.id + ' touchend.dragend' + s.id
var dragdist
var $innercontainer = $maincontainer.find('> div').css({transformStyle: 'preserve-3d'})
var $sides = $innercontainer.find('> div')
var animatetimer = null
var autorotatetimer = null
var autorotatepause = (transform3d)? s.pause + s.fxduration : s.pause
var panelClasses ={
frontpanel: 'rotateY(0deg) translate3D(0, 0, 0)',
leftpanel: constructTransform(-90, -containerwidth/2, 0, containerwidth/2),
rightpanel: constructTransform(90, containerwidth/2, 0, containerwidth/2),
front_to_right: constructTransform(90, containerwidth/2, 0, containerwidth/2),
front_to_left: constructTransform(-90, -containerwidth/2, 0, containerwidth/2),
to_front: 'rotateY(0deg) translate3D(0, 0, 0)'
}
$maincontainer.data('info', {frontside: 0, otherside: 1, width: containerwidth, $sides: $sides})
$sides
.eq(0)
.html( setslidehtml(s.images[0], s.desc[0], s) ) // заполнить передний слайд первым изображением
.css({transform: panelClasses.frontpanel})
.end().eq(1).css({visibility: 'hidden'}) // скрыть другую панель
this.rotatecube = function(dir, autocall){ // Открытый метод для поворота панели. 1-й параметр = "назад" или "вперед"
if (transform3d && transitioninProgress)
return
transitioninProgress = true
if (typeof autocall == 'undefined')
clearInterval(autorotatetimer)
var dir = (dir == 'back')? 'right' : (dir == 'forward')? 'left' : dir // перевести «назад» или «вперед» на «вправо» и «влево» внутри, соответственно
var nextimage = (dir == 'left')? (curimage < totalimages-1? curimage+1 : 0) : (curimage == 0? totalimages-1 : curimage-1)
if (transform3d){
var cubeinfo = $maincontainer.data('info')
var curfront = cubeinfo.frontside
var curotherside = cubeinfo.otherside
cubeinfo.$sides
.css({transitionDuration: '0s'})
.eq(cubeinfo.otherside)
.html( setslidehtml(s.images[nextimage], s.desc[nextimage], s) )
.css({visibility: 'visible', transform: dir=='right'? panelClasses.leftpanel : panelClasses.rightpanel})
curimage = nextimage
clearTimeout(animatetimer)
animatetimer = setTimeout(function(){ // назначить классы CSS3 для анимации после задержки 500 миллисекунд
cubeinfo.$sides
.css({transitionDuration: s.fxduration + 'ms'})
.eq(curfront)
.css({transform: dir=='right'? panelClasses.front_to_right : panelClasses.front_to_left})
.end().eq(curotherside)
.css({transform: panelClasses.to_front})
}, 50)
}
else{ // нет преобразования css3 3d, просто изменить изображение
$sides.eq(0)
.html( setslidehtml(s.images[nextimage], s.desc[nextimage], s) )
curimage = nextimage
}
}
for (var i=0; i < s.images.length; i++){ // предварительно загружать изображения
preloadimages[i] = new Image()
preloadimages[i].src = s.images[i][0]
}
if (s.pause > 0){
autorotatetimer = setInterval(function(){
thisinst.rotatecube('forward', true)
}, autorotatepause)
$maincontainer.on('mouseenter', function(){
clearInterval(autorotatetimer)
})
$maincontainer.on('mouseleave', function(){
clearInterval(autorotatetimer)
autorotatetimer = setInterval(function(){
thisinst.rotatecube('forward', true)
}, autorotatepause)
})
}
$maincontainer.on('mousedown touchstart', function(e){ // настроить поведение смахивания/перетаскивания мышью
var e = (e.type.indexOf('touch') != -1)? e.originalEvent.changedTouches[0] : e
var mousex = e.pageX
var clicktime = new Date().getTime()
dragdist = 0
$(document).on(mousemoveevtstr, function(e){
var e = (e.type.indexOf('touch') != '-1')? e.originalEvent.changedTouches[0] : e
dragdist=e.pageX-mousex // расстояние, сдвинутое по горизонтали
return false // отменить действие перетаскивания по умолчанию
})
$(document).on(mouseupevtstr, function(e){
var e = (e.type.indexOf('touch') != -1)? e.originalEvent.changedTouches[0] : e
$(document).unbind(mousemoveevtstr)
$(document).unbind(mouseupevtstr)
var dragtime = new Date().getTime() - clicktime
if ( Math.abs(dragdist) > s.swipethreshold[0] && dragtime < s.swipethreshold[1] ){
var dir = (dragdist < 0)? 'forward' : 'back'
thisinst.rotatecube(dir)
}
if (e.type == "mouseup")
return false
})
if (e.type == "mousedown")
return false // отменить действие перетаскивания по умолчанию
})
$maincontainer.on('click', function(e){
if (Math.abs(dragdist) > 0 && e.target.tagName == 'IMG') // отменить щелчок по ссылке изображения, если dragdist больше 0
return false
})
if (transform3d){
$sides.on('transitionend webkitTransitionEnd', function(e){
var $target = $(e.target) // target
if (/transform/i.test(e.originalEvent.propertyName)){ // проверить событие, запущенное на опоре "transform"
transitionendCount++
if (transitionendCount == 2){ // проверьте, что переход завершился на обоих соответствующих DIV панели
var cubeinfo = $maincontainer.data('info')
cubeinfo.otherside = cubeinfo.frontside // переключать назначения передней и другой панели
cubeinfo.frontside = (cubeinfo.otherside == 0)? 1 : 0
$sides
.css({transitionDuration: '0s', transform: 'none'})
.eq(cubeinfo.frontside)
.css({transform: panelClasses.frontpanel})
.end().eq(cubeinfo.otherside)
.css({visibility: 'hidden'})
transitionendCount = 0
transitioninProgress = false
}
}
}) // конец перехода
}
}
})(jQuery);
Можно скачать скрипт.
Скачать