This is a pretty nice “bad ass” JavaScript library thanks to Jorik Tangelder. I haven’t really played around it with a lot lately but it’s pretty straight forward
if you’re trying to pimp out your website with gesture controls. I know a few JQuery libraries will do the trick as well but this one is really lightweight and
is well documented.
So what is this? Hammer JS makes it easier to implement getsures controls.
Lets start with the basic formatting. I’m going to wrap everything in a div.
<div id="myNinjaWrapper"> <div class="panes wrapper"> <div class="pane hammer1"> <div class="panes"> <div class="pane">Chapter 1</div> </div> </div> <div class="pane hammer2"> <div class="panes"> <div class="pane">Chapter 2</div> </div> </div> <div class="pane hammer3"> <div class="panes"> <div class="pane">Chapter 3</div> </div> </div> <div class="pane hammer4"> <div class="panes"> <div class="pane">Chapter 4</div> </div> </div> </div> </div>
And then we can add some CSS to keep it intact.
#myNinjaWrapper { height: 600px; width: 800px; margin:0 auto; text-align:center; } .wrapper { max-height: 600px; max-width: 800px; background: #000; margin: 0 auto; } .panes { width: 100%; height: 100%; overflow: hidden; position: relative; } .pane { width: 100%; height: 100%; position: absolute; left: 0; top: 0; } .panes.animate > .pane { transition: all .3s; -webkit-transition: all .3s; } .hammer1 { background-color: #FFCC99; } .hammer2 { background-color: #3399CC; } .hammer3 { background-color: #CC9966; } .hammer4 { background-image: url('../pathto/image.jpg'); background-size:cover; }
So now make sure you have the Hammer JS library in your HTML file.
You can put content or images within your “pane” div.
That would the section that you use for content.
So let’s see the Javascript and return the Hammer js function for this application.
if (document.getElementById('myNinjaWrapper')){ var reqAnimationFrame = (function() { return window[Hammer.prefixed(window, "requestAnimationFrame")] || function(callback) { setTimeout(callback, 1000 / 60); } })(); function dirProp(direction, hProp, vProp) { return (direction & Hammer.DIRECTION_HORIZONTAL) ? hProp : vProp } /** * Carousel * @param container * @param direction * @constructor */ function HammerCarousel(container, direction) { this.container = container; this.direction = direction; this.panes = Array.prototype.slice.call(this.container.children, 0); this.containerSize = this.container[dirProp(direction, 'offsetWidth', 'offsetHeight')]; this.currentIndex = 0; this.hammer = new Hammer.Manager(this.container); this.hammer.add(new Hammer.Pan({ direction: this.direction, threshold: 10 })); this.hammer.on("panstart panmove panend pancancel", Hammer.bindFn(this.onPan, this)); this.show(this.currentIndex); } HammerCarousel.prototype = { /** * show a pane * @param {Number} showIndex * @param {Number} [percent] percentage visible * @param {Boolean} [animate] */ show: function(showIndex, percent, animate){ showIndex = Math.max(0, Math.min(showIndex, this.panes.length - 1)); percent = percent || 0; var className = this.container.className; if(animate) { if(className.indexOf('animate') === -1) { this.container.className += ' animate'; } } else { if(className.indexOf('animate') !== -1) { this.container.className = className.replace('animate', '').trim(); } } var paneIndex, pos, translate; for (paneIndex = 0; paneIndex < this.panes.length; paneIndex++) { pos = (this.containerSize / 100) * (((paneIndex - showIndex) * 100) + percent); if(this.direction & Hammer.DIRECTION_HORIZONTAL) { translate = 'translate3d(' + pos + 'px, 0, 0)'; } else { translate = 'translate3d(0, ' + pos + 'px, 0)' } this.panes[paneIndex].style.transform = translate; this.panes[paneIndex].style.mozTransform = translate; this.panes[paneIndex].style.webkitTransform = translate; } this.currentIndex = showIndex; }, /** * handle pan * @param {Object} ev */ onPan : function (ev) { var delta = dirProp(this.direction, ev.deltaX); var percent = (100 / this.containerSize) * delta; var animate = false; if (ev.type == 'panend' || ev.type == 'pancancel') { if (Math.abs(percent) > 20 && ev.type == 'panend') { this.currentIndex += (percent < 0) ? 1 : -1; } percent = 0; animate = true; } this.show(this.currentIndex, percent, animate); } }; // the horizontal pane scroller var outer = new HammerCarousel(document.querySelector(".panes.wrapper"), Hammer.DIRECTION_HORIZONTAL); // each pane should contain a vertical pane scroller Hammer.each(document.querySelectorAll(".pane .panes"), function(container) { // setup the inner scroller var inner = new HammerCarousel(container, Hammer.DIRECTION_VERTICAL); outer.hammer.get('pan').requireFailure(inner.hammer.get('pan')); }); }
And if you want a vertical slideshow, change the direction of the delta to ev.deltaY.
Or use both ev.deltaX, ev.delta Y.
But make sure you add more divs within your “panes” div since you only have on vertical div. The HTML5 example on the top shows a horizontal example.
For Example:
// for vertical getstures onPan : function (ev) { var delta = dirProp(this.direction, ev.deltaY);
And the HTML5
<div class="pane hammer1"> <div class="panes"> <div class="pane">Chapter 1</div> <div class="pane">The Story begins with...</div> <div class="pane">During the Middle of the Story...</div> </div> </div>
Yes, you Go all fucking nuts with multiple grid style directions.
onPan : function (ev) { var delta = dirProp(this.direction, ev.deltaX, ev.deltaY);
There’s lot more in terms of what Hammerjs is can do but for now, I’m just doing a really quick reference that can be used for light slideshow gestures. Most Jquery sliders have this so it’s nothing different than what’s on the current market, however, the pinch and zoom functions are pretty rad if you want to rotate divs or images or think of a cool way to drag items from your screen. HTML5 event handlers have been around for a while but it’s been wonky in the past with their default drag and drop but fortunately it’s a lot of it better now, phew.
At any rate Hammer.js is a good libary to use if you want to implement gestures that make take a lot longer with raw Javascript.