/**
* requestAnimationFrame and cancel polyfill
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
/**
* super simple carousel
* animation between panes happens with css transitions
*/
function Carousel(element)
{
var self = this;
element = $(element);
var container = $(">ul", element);
var panes = $(">ul>li", element);
var pane_width = 0;
var pane_height = 0;
var pane_count = panes.length;
var current_pane = 0;
var carousel_bottom = 0;
var carousel_top = 0;
var carousel_head = 85;
var is_expanded;
var _ypos;
/**
* initial
*/
this.init = function() {
setPaneDimensions();
$(window).on("load resize orientationchange", function() {
setPaneDimensions();
//updateOffset();
})
};
/**
* set the pane dimensions and scale the container
*/
function setPaneDimensions() {
pane_width = element.width();
panes.each(function() {
$(this).width(pane_width);
});
container.width(pane_width*pane_count);
// Set start point
carousel_top = $(window).height() - carousel_head;
setContainerOffsetY(carousel_top);
is_expanded = false;
};
this.updatePaneDimensions = function() {
var panes = $(">ul>li", element);
var paneWidth = panes.first().width();
var containerWidth = paneWidth*panes.length;
$(container).css('width', containerWidth);
// update pane count
pane_count = panes.length;
// reset current pane
this.showPane(current_pane, false);
}
/**
* show pane by index
* @param {Number} index
*/
this.showPane = function(index, animate) {
// between the bounds
index = Math.max(0, Math.min(index, pane_count-1));
current_pane = index;
var offset = -((100/pane_count)*current_pane);
setContainerOffset(offset, true);
}
function setContainerOffset(percent, animate) {
container.removeClass("animate");
if(animate) {
container.addClass("animate");
}
var px = ((pane_width * pane_count) / 100) * percent;
if(Modernizr.csstransforms3d) {
container.css("transform", "translate3d("+ percent +"%,0,0) scale3d(1,1,1)");
}
else if(Modernizr.csstransforms) {
container.css("transform", "translate("+ percent +"%,0)");
}
else {
var px = ((pane_width*pane_count) / 100) * percent;
container.css("left", px+"px");
}
}
function setContainerOffsetY(ypos, animate) {
element.removeClass("animate");
if (animate) {
element.addClass("animate");
}
_ypos = ypos;
if(Modernizr.csstransforms3d) {
element.css("transform", "translate3d(0," + ypos + "px,0) scale3d(1,1,1)");
}
else if(Modernizr.csstransforms) {
element.css("transform", "translate(0," + ypos + "px)");
}
else {
element.css("top", ypos + "px");
}
}
this.next = function() { return this.showPane(current_pane+1, true); };
this.prev = function() { return this.showPane(current_pane-1, true); };
this.togglePane = function(expand) {
// TODO: 'expand'
if (!is_expanded) {
// Expand
self.expand();
} else {
// Collapse
self.collapse();
}
}
this.expand = function() {
setContainerOffsetY(carousel_head, true);
is_expanded = true;
}
this.collapse = function() {
setContainerOffsetY(carousel_top, true);
is_expanded = false;
}
this.throttledTogglePane = _.debounce(self.togglePane, 100);
this.throttledShowPane = _.debounce(function() {
self.expand();
}, 100);
this.throttledHidePane = _.debounce(function() {
self.collapse();
}, 100);
function handleHammer(ev) {
// disable browser scrolling
ev.gesture.preventDefault();
switch(ev.type) {
case 'dragright':
case 'dragleft':
// stick to the finger
var pane_offset = -(100/pane_count) * current_pane;
var drag_offset = ((100/pane_width) * ev.gesture.deltaX) / pane_count;
// slow down at the first and last pane
if((current_pane == 0 && ev.gesture.direction == Hammer.DIRECTION_RIGHT) ||
(current_pane == pane_count-1 && ev.gesture.direction == Hammer.DIRECTION_LEFT)) {
drag_offset *= .4;
}
setContainerOffset(drag_offset + pane_offset);
break;
case 'swipeleft':
self.next();
ev.gesture.stopDetect();
break;
case 'swiperight':
self.prev();
ev.gesture.stopDetect();
break;
case 'release':
// Left & Right
// more then 50% moved, navigate
if(Math.abs(ev.gesture.deltaX) > pane_width/2) {
if(ev.gesture.direction == 'right') {
self.prev();
} else {
self.next();
}
}
else {
self.showPane(current_pane, true);
}
if ((ev.gesture.direction == "up") || (ev.gesture.direction == "down")) {
var windowHalf = ($(window).height() - (carousel_head * 2)) / 4;
if(Math.abs(ev.gesture.deltaY) > windowHalf) {
if (is_expanded) {
self.collapse();
} else {
self.expand();
}
}
else {
if (is_expanded) {
self.expand();
} else {
self.collapse();
}
}
}
break;
case 'tap':
self.throttledTogglePane();
ev.gesture.stopDetect();
break;
case 'dragup':
var drag_offset = carousel_top + ev.gesture.deltaY;
if (is_expanded) {
drag_offset = carousel_head + ev.gesture.deltaY;
// drag_offset *= .4;
}
setContainerOffsetY(drag_offset);
break;
case 'dragdown':
var drag_offset = carousel_head + ev.gesture.deltaY;
if (!is_expanded) {
console.log('not expanded', carousel_top, ev.gesture.deltaY)
drag_offset = carousel_top + ev.gesture.deltaY;
}
setContainerOffsetY(drag_offset);
break;
case 'swipeup':
console.log('swipeup')
self.throttledShowPane();
ev.gesture.stopDetect();
break;
case 'swipedown':
console.log('swipedown')
self.throttledHidePane();
ev.gesture.stopDetect();
break;
}
}
element.hammer({ drag_lock_to_axis: true })
.on("tap release dragleft dragright swipeleft swiperight dragup dragdown swipeup swipedown", handleHammer);
}
var carousel = new Carousel("#carousel");
carousel.init();
html,
body {
padding: 0;
margin: 0;
overflow: hidden;
height: 100%;
/* via http://lea.verou.me/css3patterns/#seigaiha */
background-color:#ddd;
background-image:
radial-gradient(circle at 100% 150%, #ddd 24%, white 25%, white 28%, #ddd 29%, #ddd 36%, white 36%, white 40%, transparent 40%, transparent),
radial-gradient(circle at 0 150%, #ddd 24%, white 25%, white 28%, #ddd 29%, #ddd 36%, white 36%, white 40%, transparent 40%, transparent),
radial-gradient(circle at 50% 100%, white 10%, #ddd 11%, #ddd 23%, white 24%, white 30%, #ddd 31%, #ddd 43%, white 44%, white 50%, #ddd 51%, #ddd 63%, white 64%, white 71%, transparent 71%, transparent),
radial-gradient(circle at 100% 50%, white 5%, #ddd 6%, #ddd 15%, white 16%, white 20%, #ddd 21%, #ddd 30%, white 31%, white 35%, #ddd 36%, #ddd 45%, white 46%, white 49%, transparent 50%, transparent),
radial-gradient(circle at 0 50%, white 5%, #ddd 6%, #ddd 15%, white 16%, white 20%, #ddd 21%, #ddd 30%, white 31%, white 35%, #ddd 36%, #ddd 45%, white 46%, white 49%, transparent 50%, transparent);
background-size:100px 50px;
}
#carousel, #carousel li {
padding: 0;
margin: 0;
position: relative;
}
#carousel {
/* position: absolute;
top: 0;
left: 0; */
}
#carousel ul {
padding: 0;
margin: 0;
position: relative;
}
#carousel {
/* overflow: hidden; */
width:100%;
-webkit-backface-visibility: hidden;
-webkit-transform: translate3d(0,0,0) scale3d(1,1,1);
-webkit-transform-style: preserve-3d;
}
#carousel.animate {
-webkit-transition: all .15s;
-moz-transition: all .15s;
-o-transition: all .15s;
transition: all .15s;
}
#carousel ul.animate {
-webkit-transition: all .3s;
-moz-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
}
#carousel ul {
transform: translate3d(0%,0,0) scale3d(1,1,1);
-o-transform: translate3d(0%,0,0) scale3d(1,1,1);
-ms-transform: translate3d(0%,0,0) scale3d(1,1,1);
-moz-transform: translate3d(0%,0,0) scale3d(1,1,1);
-webkit-transform: translate3d(0%,0,0) scale3d(1,1,1);
overflow: hidden;
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
}
#carousel ul {
-webkit-box-shadow: 0 0 20px rgba(0,0,0,.2);
box-shadow: 0 0 20px rgba(0,0,0,.2);
position: relative;
}
#carousel li {
float: left;
overflow: hidden;
-webkit-transform-style: preserve-3d;
-webkit-transform: translate3d(0,0,0);
}
#carousel li {
/*height: 85px;*/
background: #fff;
opacity: .8;
}
/* Sugar */
#carousel li h2 {
color: #000;
font-size: 30px;
text-align: center;
/* position: absolute;
top: 40%;
left: 0;
*/
width: 100%;
height: 85px;
text-shadow: -1px -1px 0 rgba(0,0,0,.2);
}
#carousel li p {
padding: 0 20px;
}
<html>
<head>
<title>Hammer.js Carousel</title>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<div id="carousel">
<ul>
<li class="pane1">
<h2>Swipe <small>left, right, up or down..</small></h2>
<p>DIY Shoreditch chambray ugh American Apparel fingerstache. Literally keytar cardigan pour-over letterpress kogi, direct trade Brooklyn Blue Bottle tousled. Cred typewriter flexitarian street art bitters forage, Tonx pour-over aesthetic meh quinoa dreamcatcher Brooklyn. 90's master cleanse beard, letterpress stumptown messenger bag sustainable kogi banjo. Kogi mixtape artisan fashion axe Odd Future vegan. Dreamcatcher scenester you probably haven't heard of them, art party Williamsburg chillwave Etsy Helvetica photo booth ethical gluten-free pop-up Schlitz distillery pickled. Thundercats actually hoodie, Helvetica art party whatever YOLO bespoke pop-up Odd Future freegan Pitchfork Etsy literally.</p>
<p>Roof party blog lo-fi banh mi mixtape fingerstache. Deep v Neutra locavore kale chips. Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami. Etsy kale chips asymmetrical skateboard food truck. Direct trade American Apparel Blue Bottle lo-fi raw denim. Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache. Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard. Messenger bag jean shorts meh gastropub. Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia. +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache. Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life. Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog. Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
<p>Roof party blog lo-fi banh mi mixtape fingerstache. Deep v Neutra locavore kale chips. Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami. Etsy kale chips asymmetrical skateboard food truck. Direct trade American Apparel Blue Bottle lo-fi raw denim. Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache. Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard. Messenger bag jean shorts meh gastropub. Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia. +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache. Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life. Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog. Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
</li>
<li class="pane2">
<h2>...or drag...</h2>
<p>Occupy Thundercats sriracha, DIY Shoreditch chambray ugh American Apparel fingerstache. Literally keytar cardigan pour-over letterpress kogi, direct trade Brooklyn Blue Bottle tousled. Cred typewriter flexitarian street art bitters forage, Tonx pour-over aesthetic meh quinoa dreamcatcher Brooklyn. 90's master cleanse beard, letterpress stumptown messenger bag sustainable kogi banjo. Kogi mixtape artisan fashion axe Odd Future vegan. Dreamcatcher scenester you probably haven't heard of them, art party Williamsburg chillwave Etsy Helvetica photo booth ethical gluten-free pop-up Schlitz distillery pickled. Thundercats actually hoodie, Helvetica art party whatever YOLO bespoke pop-up Odd Future freegan Pitchfork Etsy literally.</p>
<p>Roof party blog lo-fi banh mi mixtape fingerstache. Deep v Neutra locavore kale chips. Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami. Etsy kale chips asymmetrical skateboard food truck. Direct trade American Apparel Blue Bottle lo-fi raw denim. Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache. Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard. Messenger bag jean shorts meh gastropub. Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia. +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache. Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life. Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog. Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
<p>Roof party blog lo-fi banh mi mixtape fingerstache. Deep v Neutra locavore kale chips. Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami. Etsy kale chips asymmetrical skateboard food truck. Direct trade American Apparel Blue Bottle lo-fi raw denim. Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache. Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p>
</li>
<li class="pane3"><h2>...or swipe...</h2></li>
<li class="pane4"><h2>..or drag...</h2></li>
<li class="pane5"><h2>Dit is het einde!</h2></li>
</ul>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/hammer.js/1.0.6/hammer.min.js"></script>
<script src="http://www.dfjs.co.uk/slider/jquery.hammer.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.7.1/modernizr.min.js"></script>
</body>
</html>