3D Responsive Split Carousel With jQuery And CSS3
| File Size: | 3.46 KB |
|---|---|
| Views Total: | 10089 |
| Last Update: | |
| Publish Date: | |
| Official Website: | Go to website |
| License: | MIT |
This is a pretty cool Split 3D Carousel written in jQuery and CSS3 which enables you to slide through 2 associated cubes in different directions with side navigation and keyboard interactions.
How to use it:
1. The primary HTML structure for the split 3D carousel.
<div class="carousel">
<div class="carousel__control"> </div>
<div class="carousel__stage">
<div class="spinner spinner--left">
<div class="spinner__face js-active" data-bg="#27323c">
<div class="content" data-type="carousel-1">
<div class="content__left">
<h1>Title 1<br>
<span>Subtitle 1</span></h1>
</div>
<div class="content__right">
<div class="content__main">
<p>Description 1</p>
</div>
<h3 class="content__index">01</h3>
</div>
</div>
</div>
<div class="spinner__face" data-bg="#19304a">
<div class="content" data-type="carousel-2">
<div class="content__left">
<h1>Title 2<br>
<span>Subtitle 2</span></h1>
</div>
<div class="content__right">
<div class="content__main">
<p>Description 2</p>
</div>
<h3 class="content__index">02</h3>
</div>
</div>
</div>
<div class="spinner__face" data-bg="#2b2533">
<div class="content" data-type="carousel-3">
<div class="content__left">
<h1>Title 3<br>
<span>Subtitle 3</span></h1>
</div>
<div class="content__right">
<div class="content__main">
<p>Description 3</p>
</div>
<h3 class="content__index">03</h3>
</div>
</div>
</div>
<div class="spinner__face" data-bg="#312f2d">
<div class="content" data-type="carousel-4">
<div class="content__left">
<h1>Title 4<br>
<span>Subtitle 4</span></h1>
</div>
<div class="content__right">
<div class="content__main">
<p>Description 4</p>
</div>
<h3 class="content__index">04</h3>
</div>
</div>
</div>
</div>
</div>
</div>
2. The primary CSS/CSS3 styles:
.carousel {
position: relative;
height: 100%;
overflow: hidden;
-webkit-perspective: 50vw;
perspective: 50vw;
-webkit-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
.carousel__stage {
position: absolute;
top: 20px;
bottom: 20px;
left: 20px;
right: 20px;
margin: auto;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform: translateZ(calc(-50vh + 20px));
transform: translateZ(calc(-50vh + 20px));
}
.spinner {
position: absolute;
width: calc(50vw - (20px));
height: calc(100vh - 40px);
top: 0;
left: 0;
right: auto;
bottom: 0;
margin: auto;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
transition: -webkit-transform 1s;
transition: transform 1s;
transition: transform 1s, -webkit-transform 1s;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: rotateX(0);
transform: rotateX(0);
}
.js-spin-fwd .spinner {
-webkit-transform: rotateX(-90deg);
transform: rotateX(-90deg);
}
.js-spin-bwd .spinner {
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
}
.js-spin-fwd .spinner--right {
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
}
.js-spin-bwd .spinner--right {
-webkit-transform: rotateX(-90deg);
transform: rotateX(-90deg);
}
.spinner--right {
right: 0;
left: auto;
}
.spinner__face {
display: none;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
.spinner__face.js-next {
display: block;
-webkit-transform: rotateX(90deg) translateZ(calc(50vh - 20px));
transform: rotateX(90deg) translateZ(calc(50vh - 20px));
}
.spinner--right .spinner__face.js-next {
-webkit-transform: rotateX(270deg) translateZ(calc(50vh - 20px));
transform: rotateX(270deg) translateZ(calc(50vh - 20px));
}
.js-spin-bwd .spinner__face.js-next {
-webkit-transform: rotateX(-90deg) translateZ(calc(50vh - 20px));
transform: rotateX(-90deg) translateZ(calc(50vh - 20px));
}
.js-spin-bwd .spinner--right .spinner__face.js-next {
-webkit-transform: rotateX(-270deg) translateZ(calc(50vh - 20px));
transform: rotateX(-270deg) translateZ(calc(50vh - 20px));
}
.js-active {
display: block;
-webkit-transform: translateZ(calc(50vh - 20px));
transform: translateZ(calc(50vh - 20px));
}
.content {
position: absolute;
width: 200%;
height: 100%;
left: 0;
}
.spinner--right .content { left: -100%; }
.content__left, .content__right {
position: absolute;
left: 0;
top: 0;
width: 50%;
height: 100%;
}
.content__right {
right: 0;
left: auto;
}
.content__left {
background-repeat: no-repeat;
background-size: cover;
}
.content__left:after {
position: absolute;
display: block;
content: "";
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.1);
}
.content__left h1 {
position: absolute;
top: 50%;
margin-top: -3vw;
text-align: center;
font-family: oswald;
font-size: 5vw;
height: 10vw;
opacity: 1;
color: #fff;
width: 100%;
letter-spacing: 0.15em;
line-height: 0.6;
}
.content__left span {
font-size: 1vw;
font-weight: 300;
letter-spacing: 0.2em;
opacity: 0.9;
font-family: Merriweather;
}
.content__right {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.content__right .content__main {
position: absolute;
font-family: Merriweather, serif;
text-align: left;
color: #fff;
font-size: 1.3vw;
padding: 0 8vw;
line-height: 1.65;
font-weight: 300;
margin: 0;
opacity: 0.8;
}
.content__right .content__main p:last-child {
text-transform: uppercase;
letter-spacing: 0.15em;
font-size: 0.85em;
}
.content__right .content__index {
font-size: 30vh;
position: absolute;
right: -1vh;
top: 35vh;
opacity: 0.04;
font-family: oswald;
color: #fff;
}
3. Add background images to the carousel.
[data-type="carousel-1"] .content__left { background-image: url("1.jpg"); }
.spinner--right [data-type="carousel-1"] .content__left { background-image: none; }
[data-type="carousel-2"] .content__left { background-image: url("2.jpg"); }
.spinner--right [data-type="carousel-2"] .content__left { background-image: none; }
[data-type="carousel-3"] .content__left { background-image: url("3.jpg"); }
.spinner--right [data-type="carousel-3"] .content__left { background-image: none; }
[data-type="carousel-4"] .content__left { background-image: url("4.jpg"); }
.spinner--right [data-type="carousel-4"] .content__left { background-image: none; }
4. The Split 3D Carousel requires the latest version of jQuery library loaded at the end of the document.
<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
5. The main jQuery script to active the Split 3D Carousel. Add the following JS snippets after your jQuery library and done.
var activeIndex = 0;
var limit = 0;
var disabled = false;
var $stage = undefined;
var $controls = undefined;
var canvas = false;
var SPIN_FORWARD_CLASS = 'js-spin-fwd';
var SPIN_BACKWARD_CLASS = 'js-spin-bwd';
var DISABLE_TRANSITIONS_CLASS = 'js-transitions-disabled';
var SPIN_DUR = 1000;
var appendControls = function appendControls() {
for (var i = 0; i < limit; i++) {
$('.carousel__control').append('<a href="#" data-index="' + i + '"></a>');
}
var height = $('.carousel__control').children().last().outerHeight();
$('.carousel__control').css('height', 30 + limit * height);
$controls = $('.carousel__control').children();
$controls.eq(activeIndex).addClass('active');
};
var setIndexes = function setIndexes() {
$('.spinner').children().each(function (i, el) {
$(el).attr('data-index', i);
limit++;
});
};
var duplicateSpinner = function duplicateSpinner() {
var $el = $('.spinner').parent();
var html = $('.spinner').parent().html();
$el.append(html);
$('.spinner').last().addClass('spinner--right');
$('.spinner--right').removeClass('spinner--left');
};
var paintFaces = function paintFaces() {
$('.spinner__face').each(function (i, el) {
var $el = $(el);
var color = $(el).attr('data-bg');
$el.children().css('backgroundImage', 'url(' + getBase64PixelByColor(color) + ')');
});
};
var getBase64PixelByColor = function getBase64PixelByColor(hex) {
if (!canvas) {
canvas = document.createElement('canvas');
canvas.height = 1;
canvas.width = 1;
}
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = hex;
ctx.fillRect(0, 0, 1, 1);
return canvas.toDataURL();
}
return false;
};
var prepareDom = function prepareDom() {
setIndexes();
paintFaces();
duplicateSpinner();
appendControls();
};
var spin = function spin() {
var inc = arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];
if (disabled)
return;
if (!inc)
return;
activeIndex += inc;
disabled = true;
if (activeIndex >= limit) {
activeIndex = 0;
}
if (activeIndex < 0) {
activeIndex = limit - 1;
}
var $activeEls = $('.spinner__face.js-active');
var $nextEls = $('.spinner__face[data-index=' + activeIndex + ']');
$nextEls.addClass('js-next');
if (inc > 0) {
$stage.addClass(SPIN_FORWARD_CLASS);
} else {
$stage.addClass(SPIN_BACKWARD_CLASS);
}
$controls.removeClass('active');
$controls.eq(activeIndex).addClass('active');
setTimeout(function () {
spinCallback(inc);
}, SPIN_DUR, inc);
};
var spinCallback = function spinCallback(inc) {
$('.js-active').removeClass('js-active');
$('.js-next').removeClass('js-next').addClass('js-active');
$stage.addClass(DISABLE_TRANSITIONS_CLASS).removeClass(SPIN_FORWARD_CLASS).removeClass(SPIN_BACKWARD_CLASS);
$('.js-active').each(function (i, el) {
var $el = $(el);
$el.prependTo($el.parent());
});
setTimeout(function () {
$stage.removeClass(DISABLE_TRANSITIONS_CLASS);
disabled = false;
}, 100);
};
var attachListeners = function attachListeners() {
document.onkeyup = function (e) {
switch (e.keyCode) {
case 38:
spin(-1);
break;
case 40:
spin(1);
break;
}
};
$controls.on('click', function (e) {
e.preventDefault();
if (disabled)
return;
var $el = $(e.target);
var toIndex = parseInt($el.attr('data-index'), 10);
spin(toIndex - activeIndex);
});
};
var assignEls = function assignEls() {
$stage = $('.carousel__stage');
};
var init = function init() {
assignEls();
prepareDom();
attachListeners();
};
$(function () {
init();
});
This awesome jQuery plugin is developed by paulnoble. For more Advanced Usages, please check the demo page or visit the official website.










