Parallax slider (JS animations)
by Eric Hynds
HTML
<div id="buttons">
<button id="prev">Prev</button>
<button id="next">Next</button>
</div>
<ul id="pages"></ul>
<div id="hero-container">
<div class="hero-image" style="background-image: url(http://placeimg.com/640/480/any?1)">
<div class="hero-text">
<div>HERO 1</div>
<div>More info on Hero 1.</div>
</div>
</div>
<div class="hero-image" style="background-image: url(http://placeimg.com/640/480/any?2)">
<div class="hero-text">
<div>HERO 2</div>
<div>More info on Hero 2.</div>
</div>
</div>
<div class="hero-image" style="background-image: url(http://placeimg.com/640/480/any?3)">
<div class="hero-text">
<div>HERO 3</div>
<div>More info on Hero 3.</div>
</div>
</div>
</div>
CSS
html, body {
width: 100%;
height: 100%;
margin: 0;
}
#buttons {
position: absolute;
z-index: 20;
top: 20px;
left: 20px;
}
#pages {
position: absolute;
z-index: 20;
top: 25px;
left: 120px;
list-style: none;
margin: 0;
padding: 0;
overflow: hidden;
}
#pages li {
float: left;
margin: 0 5px;
color: #fff;
border: 1px solid #fff;
width: 8px;
height: 8px;
display: block;
}
#pages li.is-active {
background: #fff;
}
.hero-image:first-child {
display: block;
z-index: 5;
}
.hero-image.in-slide {
top: 100%;
display: block;
z-index: 10;
}
.hero-image.in-slide .hero-text {
top: 200%;
}
.reverse .hero-image.in-slide {
top: -100%;
}
.reverse .hero-image.in-slide .hero-text {
top: -200%;
}
#hero-container {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.hero-image {
background-color: #000;
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
position: absolute;
}
.hero-text {
position: absolute;
left: 10%;
top: 70%;
color: #FFF;
font-family: sans-serif;
font-size: 30px;
text-shadow: 0px 0px 8px black, 0px 0px 2px black;
}
JavaScript
(function() {
function Parallax(elem, opts) {
this.opts = $.extend(Parallax.defaults, opts || {});
this.$container = $(elem);
this.$slides = this.$container.children();
this.$text = this.$slides.find('.hero-text');
this.$slides.each(function(index) {
$.data(this, 'index', index);
});
this._initPagination();
this._startTimer();
}
Parallax.prototype._initPagination = function() {
if(!this.opts.pages) return;
var $pages = this.opts.pages;
var activeClass = this.opts.activeClass;
$pages.html(function() {
return this.$slides.map(function(index) {
return '<li class="' + (index ? '' : activeClass) + '"></li>';
}).get().join('');
}.bind(this));
this.$container.on('parallax:moved', function(event, data) {
var $lis = $pages.children();
$lis.removeClass(activeClass);
$lis.eq(data.$in.data('index')).addClass(activeClass);
}.bind(this));
};
Parallax.prototype._startTimer = function() {
if(!this.opts.autoscroll) return;
clearTimeout(this.timer);
this.timer = setTimeout(this.next.bind(this), this.opts.autoscroll);
};
Parallax.prototype._done = function(dir, $in, $out) {
if(dir === 'next') {
this.$container.append($out);
} else {
this.$container.prepend($in);
}
this.isTransitioning = false;
this.$container.removeClass('reverse');
this.$slides.removeClass('in-slide out-slide');
this.$slides.css('top', '');
this.$text.css('top', '');
this.$container.trigger('parallax:moved', { $in: $in, $out: $out });
this._startTimer();
};
Parallax.prototype.move = function(dir) {
if(this.isTransitioning) return;
this.isTransitioning = true;
var isNext = dir === 'next';
this.$container.addClass(isNext ? '' : 'reverse');
var $slides = this.$container.children();
var $in = $slides.eq(isNext ? 1 : -1);
var $out = $slides.eq(0);
var $inText = $in.find('.hero-text');
var...