From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
In this tutorial we’ll create a fullscreen slideshow with a twist: we’ll slice the current slide open in order to reveal the next or previous slide. Using different data-attributes, we’ll define the type, rotation angle and scale of a slide’s parts, giving us the possibility to create unique effects of each slide transition.
We’ll be using jQuery cond, jQuery plugin by Ben Alman for chainable “if-then-else” statements.
The animal icon font that we’ll be using is by Alan Carr and you can find it here.
The images in the second demo are by Majownik and they are licensed under a Creative Commons Attribution License.
Let’s start with the HTML.
The Markup
Our initial markup will consist of a main container with the class and id sl-slide-wrapper which will hold the slider and all the slides, each one having the class sl-slide. Then, we will add two types of navigation, one will be the arrows to go to the previous and next slide and the other will be the dots for navigating directly to a certain slide. We’ll also add a background class to each slide which will control the background color of every slide.
<div id="slider" class="sl-slider-wrapper"> <div class="sl-slider"> <div class="sl-slide bg-1"> <div class="sl-slide-inner"> <div class="deco" data-icon="H"></div> <h2>A bene placito</h2> <blockquote> <p>You have just dined...</p> <cite>Ralph Waldo Emerson</cite> </blockquote> </div> </div> <div class="sl-slide bg-2"> <div class="sl-slide-inner"> <div class="deco" data-icon="q"></div> <h2>Regula aurea</h2> <blockquote> <p>Until he extends the circle...</p> <cite>Albert Schweitzer</cite> </blockquote> </div> </div> <div class="sl-slide bg-2"> <!-- ... --> </div> <!-- ... --> </div> <nav id="nav-arrows" class="nav-arrows"> <span class="nav-arrow-prev">Previous</span> <span class="nav-arrow-next">Next</span> </nav> <nav id="nav-dots" class="nav-dots"> <span class="nav-dot-current"></span> <span></span> <span></span> <span></span> <span></span> </nav> </div>
Every slide will also have some data-attributes that we will use in order to control the effect for each slide. The data attributes that we want are the following:
data-orientation data-slice1-rotation data-slice2-rotation data-slice1-scale data-slice2-scale
The first one, data-orientation should be either “vertical” or “horizontal”. This we need in order to know where to “slice” the slide. It will be either slice horizontally or vertically. The data-slice1-rotation and data-slice2-rotation value will be the rotation degree for each one of the slices and the data-slice1-scale and data-slice2-scale value will be the scale value.
So, our first slide will have something like this:
<div class="sl-slide" data-orientation="horizontal" data-slice1-rotation="-25" data-slice2-rotation="-25" data-slice1-scale="2" data-slice2-scale="2">
Our structure is a “base structure”. We will build upon that structure using JavaScript in order to be able to create the effects. So, we will want to transform it into this (each slide will also have the data attributes):
<div id="slider" class="sl-slider-wrapper"> <div class="sl-slider"> <div class="sl-slides-wrapper"> <div class="sl-slide bg-1 sl-slide-horizontal"> <div class="sl-content-wrapper"> <div class="sl-content"> <!-- the content --> </div> </div> </div> <!-- ... --> </div> </div> <!-- navs --> </div>
The content will basically be our “sl-slide-inner” and everything that is inside of it.
In the moment that we navigate to the next or previous slide we will take the current slide and duplicate its content wrapper, creating the “slices”:
<div class="sl-slide sl-slide-horizontal" > <div class="sl-content-slice"> <div class="sl-content-wrapper"> <div class="sl-content"> <!-- ... --> </div> </div> </div> <div class="sl-content-slice"> <div class="sl-content-wrapper"> <div class="sl-content"> <!-- ... --> </div> </div> </div> </div>
Now, let’s style it!
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The CSS
Note, that we will omit vendor prefixes here.
Since we will make a reusable plugin out of this we don’t want the slider to be fullscreen by default. So, we won’t set the default style of the wrapper to 100% width and height but to this:
.sl-slider-wrapper { width: 800px; height: 400px; margin: 0 auto; position: relative; overflow: hidden; }
The slider will be of position absolute and we’ll set the top and left to zero. The width and height will be set dynamically with JavaScript.
The slides, the dyamic wrapper and the inner part will all need absolute positioning and they’ll have a width and height of 100%:
.sl-slider { position: absolute; top: 0; left: 0; } .sl-slide, .sl-slides-wrapper, .sl-slide-inner { position: absolute; width: 100%; height: 100%; top: 0; left: 0; }
Each slide should have a z-index of 1; we’ll control the appearance and the stacking of the slides with JavaScript:
.sl-slide { z-index: 1; }
The content “slices” will be positioned absolutely and their common style is the following:
/* The duplicate parts/slices */ .sl-content-slice { overflow: hidden; position: absolute; box-sizing: content-box; background: #fff; }
We use box-sizing: content-box here because by default we use border-box .
The content “slices” will be horizontal or vertical, meaning that either the height or the width will be half of the screensize. In order to avoid seeing the edges of a slice when we rotate it, we’ll add some paddings.
/* Horizontal slice */ .sl-slide-horizontal .sl-content-slice { width: 100%; height: 50%; left: -200px; } .sl-slide-horizontal .sl-content-slice:first-child { top: -200px; padding: 200px 200px 0px 200px; } .sl-slide-horizontal .sl-content-slice:nth-child(2) { top: 50%; padding: 0px 200px 200px 200px; } /* Vertical slice */ .sl-slide-vertical .sl-content-slice { width: 50%; height: 100%; top: -200px; } .sl-slide-vertical .sl-content-slice:first-child { left: -200px; padding: 200px 0px 200px 200px; } .sl-slide-vertical .sl-content-slice:nth-child(2) { left: 50%; padding: 200px 200px 200px 0px; }
We use negative position values in order to “pull” the divisions into place.
Let’s style the content wrapper and the content division:
/* Content wrapper */ /* Width and height is set dynamically */ .sl-content-wrapper { position: absolute; } .sl-content { width: 100%; height: 100%; background: #fff; }
The division with the class sl-content-wrapper will get a height and width dynamically. If, for example, the slide is horizontal, the wrapper will have a width of 100% of the parent’s container width and 50% of the parent’s container height. The wrapper of the second slice will also have a negative top (horizontal) or left (vertical) margin in order to “pull” the duplicated content up or to the left.
This is all the styling for the slider to work by default. Let’s take a look at some custom elements, like the nav items and the content elements that we’ll animate when we navigate through the slides.
For the navigation arrows we will use this image-less technique. We’ll simply have a little box and rotate it 45 degrees. Then we’ll add some border to the sides and voilà, we made ourselves some neat arrows:
/* Custom navigation arrows */ .nav-arrows span { position: absolute; z-index: 2000; top: 50%; width: 40px; height: 40px; border: 8px solid #ddd; border: 8px solid rgba(150,150,150,0.4); text-indent: -90000px; margin-top: -40px; cursor: pointer; transform: rotate(45deg); } .nav-arrows span:hover { border-color: rgba(150,150,150,0.9); } .nav-arrows span.nav-arrow-prev { left: 5%; border-right: none; border-top: none; } .nav-arrows span.nav-arrow-next { right: 5%; border-left: none; border-bottom: none; }
Now, let’s style the navigation dots. We’ll position them absolutely and make the span display as inline-blocks so that we can somply center them. They will look like little dots because we’ll apply a border radius of 50% to them. With some box shadows, we’ll make them look inset. The currently active navigation dot will have a pseudo-element (white dot) which will be placed on top of it:
.nav-dots { text-align: center; position: absolute; bottom: 2%; height: 30px; width: 100%; left: 0; z-index: 1000; } .nav-dots span { display: inline-block; position: relative; width: 16px; height: 16px; border-radius: 50%; margin: 3px; background: #ddd; background: rgba(150,150,150,0.4); cursor: pointer; box-shadow: 0 1px 1px rgba(255,255,255,0.4), inset 0 1px 1px rgba(0,0,0,0.1); } .nav-dots span.nav-dot-current:after { content: ""; position: absolute; width: 10px; height: 10px; top: 3px; left: 3px; border-radius: 50%; background: rgba(255,255,255,0.8); }
The elements that we’ll use in the content will be a decorative element (the animal with the circles), a headline and a blockquote. We’ll use a font to give us some cute animal “icons” that we’ll place as a pseudo element of the decorative div.
The division with the class deco, just like all the other content elements, will have an absolute position. We’ll center it horizontally and give it a bottom value of 50%:
.deco { width: 260px; height: 260px; border: 2px dashed #ddd; border: 2px dashed rgba(150,150,150,0.4); border-radius: 50%; position: absolute; bottom: 50%; left: 50%; margin: 0 0 0 -130px; }
We use a data attribute “data-icon” in the decorative element and we’ll style the pseudo-element :after to contain the letter from the animal icon font as its content:
[data-icon]:after { content: attr(data-icon); font-family: 'AnimalsNormal'; color: #999; text-shadow: 0 0 1px #999; position: absolute; width: 220px; height: 220px; line-height: 220px; text-align: center; font-size: 100px; top: 50%; left: 50%; margin: -110px 0 0 -110px; box-shadow: inset 0 0 0 10px #f7f7f7; border-radius: 50%; }
The box shadow will create a “fake” inset border.
The headline will also be positioned absolutely and we’ll give it the same bottom value like we gave to the decorative element, which is 50%. We then add a negative bottom margin in order to place it under the other element. Like that we can use the decorative element as a reference point and position the other elements relatively to it using a negative bottom margin:
.sl-slide h2 { color: #000; text-shadow: 0 0 1px #000; padding: 20px; position: absolute; font-size: 34px; font-weight: 700; letter-spacing: 13px; text-transform: uppercase; width: 80%; left: 10%; text-align: center; line-height: 50px; bottom: 50%; margin: 0 0 -120px 0; }
The blockquote will be of 100% width and we will center the paragraph inside which will have a maximum width of 400 pixel:
.sl-slide blockquote { position: absolute; width: 100%; text-align: center; left: 0; font-weight: 400; font-size: 14px; line-height: 20px; height: 70px; color: #8b8b8b; z-index: 2; bottom: 50%; margin: 0 0 -200px 0; padding: 0; } .sl-slide blockquote p{ margin: 0 auto; width: 60%; max-width: 400px; position: relative; }
Let’s add a quotation mark to the blockquote. Using the pseudo-class :before, we’ll add a over-sized quotation mark behind the blockquote:
.sl-slide blockquote p:before { color: #f0f0f0; color: rgba(244,244,244,0.65); font-family: "Bookman Old Style", Bookman, Garamond, serif; position: absolute; line-height: 60px; width: 75px; height: 75px; font-size: 200px; z-index: -1; left: -80px; top: 35px; content: '201C'; }
And the cite will have a different look:
.sl-slide blockquote cite { font-size: 10px; padding-top: 10px; display: inline-block; font-style: normal; text-transform: uppercase; letter-spacing: 4px; }
Next, we’ll define some classes for controling the colors of the slides. When we give this color class to the slide, we want the background color and the color of the elements to be different. By default, our slides are white/gray and the content elements are black and gray.
We also need to give the same background color to the dynamic slice element, the one that will have a large padding:
/* First Slide */ .bg-1 .sl-slide-inner, .bg-1 .sl-content-slice { background: #fff; } /* Second Slide */ .bg-2 .sl-slide-inner, .bg-2 .sl-content-slice { background: #000; } .bg-2 [data-icon]:after, .bg-2 h2 { color: #fff; } .bg-2 blockquote:before { color: #222; } /* Third Slide */ .bg-3 .sl-slide-inner, .bg-3 .sl-content-slice { background: #db84ad; } .bg-3 .deco { border-color: #fff; border-color: rgba(255,255,255,0.5); } .bg-3 [data-icon]:after { color: #fff; text-shadow: 0 0 1px #fff; box-shadow: inset 0 0 0 10px #b55381; } .bg-3 h2, .bg-3 blockquote{ color: #fff; text-shadow: 0px 1px 1px rgba(0,0,0,0.3); } .bg-3 blockquote:before { color: #c46c96; } /* Forth Slide */ .bg-4 .sl-slide-inner, .bg-4 .sl-content-slice { background: #5bc2ce; } .bg-4 .deco { border-color: #379eaa; } .bg-4 [data-icon]:after { text-shadow: 0 0 1px #277d87; color: #277d87; } .bg-4 h2, .bg-4 blockquote{ color: #fff; text-shadow: 1px 1px 1px rgba(0,0,0,0.2); } .bg-4 blockquote:before { color: #379eaa; } /* Fifth Slide */ .bg-5 .sl-slide-inner, .bg-5 .sl-content-slice { background: #ffeb41; } .bg-5 .deco { border-color: #ECD82C; } .bg-5 .deco:after { color: #000; text-shadow: 0 0 1px #000; } .bg-5 h2, .bg-5 blockquote{ color: #000; text-shadow: 1px 1px 1px rgba(0,0,0,0.1); } .bg-5 blockquote:before { color: #ecd82c; }
And now, let’s add some motion to the content elements! When we navigate the slides, we want the content elements to do something fun, so we will add a class to the next slide whenever we navigate to the “right” (or “in” since this almost looks like as if we are moving further). That class will “trigger” an animation for each one of the content elements:
/* Animations for elements */ .sl-trans-elems .deco{ animation: roll 1s ease-out both; } .sl-trans-elems h2{ animation: moveUp 1s ease-in-out both; } .sl-trans-elems blockquote{ animation: fadeIn 0.5s linear 0.5s both; } @keyframes roll{ 0% {transform: translateX(500px) rotate(360deg); opacity: 0;} 100% {transform: translateX(0px) rotate(0deg); opacity: 1;} } @keyframes moveUp{ 0% {transform: translateY(40px);} 100% {transform: translateY(0px);} } @keyframes fadeIn{ 0% {opacity: 0;} 100% {opacity: 1;} }
The decorative element will “roll in” from the right side, the heading will move up and the blockquote will simply fade in.
Now, when we navigate back (or “out”), we want to see the reverse happening:
.sl-trans-back-elems .deco{ animation: scaleDown 1s ease-in-out both; } .sl-trans-back-elems h2{ animation: fadeOut 1s ease-in-out both; } .sl-trans-back-elems blockquote{ animation: fadeOut 1s linear both; } @keyframes scaleDown{ 0% {transform: scale(1);} 100% {transform: scale(0.5);} } @keyframes fadeOut{ 0% {opacity: 1;} 100% {opacity: 0;} }
Here we will scale down the decorative element and simply fade out the rest.
And that’s all the style! Let’s take a look at the JavaScript.
The JavaScript
Let’s first take a look at our plugin options:
$.Slitslider.defaults = { // transitions speed speed : 800, // if true the item's slices will also animate the opacity value optOpacity : false, // amount (%) to translate both slices - adjust as necessary translateFactor : 230, // maximum possible angle maxAngle : 25, // maximum possible scale maxScale : 2, // slideshow on / off autoplay : false, // keyboard navigation keyboard : true, // time between transitions interval : 4000, // callbacks onBeforeChange : function( slide, idx ) { return false; }, onAfterChange : function( slide, idx ) { return false; } };
We can set the speed of the transitions, set the slideshow to play automatically with a specific interval and also make the slide’s slices opacity change during the transition.
The translateFactor option is the amount in percentage for translating both slices. You can adjust this value as necessary as you change the slide’s scale and angle data attributes and the maxAngle and maxScale values.
We will start by executing the _init function.
_init : function( options ) { // options this.options = $.extend( true, {}, $.Slitslider.defaults, options ); // https://github.com/twitter/bootstrap/issues/2870 this.transEndEventNames = { 'WebkitTransition' : 'webkitTransitionEnd', 'MozTransition' : 'transitionend', 'OTransition' : 'oTransitionEnd', 'msTransition' : 'MSTransitionEnd', 'transition' : 'transitionend' }; this.transEndEventName = this.transEndEventNames[ Modernizr.prefixed( 'transition' ) ]; // suport for css 3d transforms and css transitions this.support = Modernizr.csstransitions && Modernizr.csstransforms3d; // the slider this.$el = this.$elWrapper.children( '.sl-slider' ); // the slides this.$slides = this.$el.children( '.sl-slide' ).hide(); // total slides this.slidesCount = this.$slides.length; // current slide this.current = 0; // control if it's animating this.isAnimating = false; // get container size this._getSize(); // layout this._layout(); // load some events this._loadEvents(); // slideshow if( this.options.autoplay ) { this._startSlideshow(); } }
Let’s take a look at the _layout function:
_layout : function() { this.$slideWrapper = $( '<div class="sl-slides-wrapper" />' ); // wrap the slides this.$slides.wrapAll( this.$slideWrapper ).each( function( i ) { var $slide = $( this ), // vertical || horizontal orientation = $slide.data( 'orientation' ); $slide.addClass( 'sl-slide-' + orientation ) .children() .wrapAll( '<div class="sl-content-wrapper" />' ) .wrapAll( '<div class="sl-content" />' ); } ); // set the right size of the slider/slides for the current window size this._setSize(); // show first slide this.$slides.eq( this.current ).show(); }
We are wrapping the slides into a division with the class “sl-slides-wrapper”. As we’ve mentioned before, each slide’s content will also be wrapped by two divisions, one with the class sl-content and one with the class sl-content-wrapper.
We also add the respective orientation class to the slide (sl-slide-vertical or sl-slide-horizontal).
The slider and its sl-content-wrapper division need to have the main container’s width and height. That’s what we do in the _setSize function.
Finally, we’ll show the current/first slide.
In the _loadEvents function we will bind the click events for the keyboard navigation and the resize (smartresize) event to the window:
_loadEvents : function() { var self = this; $window.on( 'debouncedresize.slitslider', function( event ) { // update size values self._getSize(); // set the sizes again self._setSize(); } ); if ( this.options.keyboard ) { $document.on( 'keydown.slitslider', function(e) { var keyCode = e.keyCode || e.which, arrow = { left: 37, up: 38, right: 39, down: 40 }; switch (keyCode) { case arrow.left : self._stopSlideshow(); self._navigate( 'prev' ); break; case arrow.right : self._stopSlideshow(); self._navigate( 'next' ); break; } } ); } }
Let’s see how we “slice” the slides and move to the next one:
_navigate : function( dir, pos ) { if( this.isAnimating || this.slidesCount < 2 ) { return false; } this.isAnimating = true; var self = this, $currentSlide = this.$slides.eq( this.current ); // if position is passed if( pos !== undefined ) { this.current = pos; } // if not check the boundaries else if( dir === 'next' ) { this.current = this.current < this.slidesCount - 1 ? ++this.current : 0; } else if( dir === 'prev' ) { this.current = this.current > 0 ? --this.current : this.slidesCount - 1; } this.options.onBeforeChange( $currentSlide, this.current ); // next slide to be shown var $nextSlide = this.$slides.eq( this.current ), // the slide we want to cut and animate $movingSlide = ( dir === 'next' ) ? $currentSlide : $nextSlide, // the following are the data attrs set for each slide configData = $movingSlide.data(), config = {}; config.orientation = configData.orientation || 'horizontal', config.slice1angle = configData.slice1Rotation || 0, config.slice1scale = configData.slice1Scale || 1, config.slice2angle = configData.slice2Rotation || 0, config.slice2scale = configData.slice2Scale || 1; this._validateValues( config ); var cssStyle = config.orientation === 'horizontal' ? { marginTop : -this.size.height / 2 } : { marginLeft : -this.size.width / 2 }, // default slide's slices style resetStyle = { 'transform' : 'translate(0%,0%) rotate(0deg) scale(1)', opacity : 1 }, // slice1 style slice1Style = config.orientation === 'horizontal' ? { 'transform' : 'translateY(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' } : { 'transform' : 'translateX(-' + this.options.translateFactor + '%) rotate(' + config.slice1angle + 'deg) scale(' + config.slice1scale + ')' }, // slice2 style slice2Style = config.orientation === 'horizontal' ? { 'transform' : 'translateY(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' } : { 'transform' : 'translateX(' + this.options.translateFactor + '%) rotate(' + config.slice2angle + 'deg) scale(' + config.slice2scale + ')' }; if( this.options.optOpacity ) { slice1Style.opacity = 0; slice2Style.opacity = 0; } // we are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is either coming "next" // or going "prev" according to the direction. // the idea is to make it more interesting by giving some animations to the respective slide's elements //( dir === 'next' ) ? $nextSlide.addClass( 'sl-trans-elems' ) : $currentSlide.addClass( 'sl-trans-back-elems' ); $currentSlide.removeClass( 'sl-trans-elems' ); var transitionProp = { 'transition' : 'all ' + this.options.speed + 'ms ease-in-out' }; // add the 2 slices and animate them $movingSlide.css( 'z-index', this.slidesCount ) .find( 'div.sl-content-wrapper' ) .wrap( $( '<div class="sl-content-slice" />' ).css( transitionProp ) ) .parent() .cond( dir === 'prev', function() { var slice = this; this.css( slice1Style ); setTimeout( function() { slice.css( resetStyle ); }, 50 ); }, function() { var slice = this; setTimeout( function() { slice.css( slice1Style ); }, 50 ); } ) .clone() .appendTo( $movingSlide ) .cond( dir === 'prev', function() { var slice = this; this.css( slice2Style ); setTimeout( function() { $currentSlide.addClass( 'sl-trans-back-elems' ); if( self.support ) { slice.css( resetStyle ).on( self.transEndEventName, function() { self._onEndNavigate( slice, $currentSlide, dir ); } ); } else { self._onEndNavigate( slice, $currentSlide, dir ); } }, 50 ); }, function() { var slice = this; setTimeout( function() { $nextSlide.addClass( 'sl-trans-elems' ); if( self.support ) { slice.css( slice2Style ).on( self.transEndEventName, function() { self._onEndNavigate( slice, $currentSlide, dir ); } ); } else { self._onEndNavigate( slice, $currentSlide, dir ); } }, 50 ); } ) .find( 'div.sl-content-wrapper' ) .css( cssStyle ); $nextSlide.show(); }
So, the trick is to duplicate the slide’s content into the divisions with the class sl-content-slice and to set the second one’s margin-left or margin-top to half the container’s width or height. That will make everything look “normal” and we won’t see any separation.
Then, according to the values defined in the element’s data attributes, we’ll animate the slide’s slices.
According to the direction, we will either slice the current slide and show the next one, or we will slice the previous one (not shown), and put together its slices on top of the current one.
We are adding the classes sl-trans-elems and sl-trans-back-elems to the slide that is next (when we navigate “next”) or the current one (when we navigate “prev”). Like we have seen before in the CSS part, adding those classes will make the content elements of the respective slide animate in a specific way.
Once the transition ends, we call the _onEndNavigate function where we will unwrap the content of the current slide, thus removing the two sl-content-slice divisions:
_onEndNavigate : function( $slice, $oldSlide, dir ) { // reset previous slide's style after next slide is shown var $slide = $slice.parent(), removeClasses = 'sl-trans-elems sl-trans-back-elems'; // remove second slide's slice $slice.remove(); // unwrap.. $slide.css( 'z-index', 1 ) .find( 'div.sl-content-wrapper' ) .unwrap(); // hide previous current slide $oldSlide.hide().removeClass( removeClasses ); $slide.removeClass( removeClasses ); // now we can navigate again.. this.isAnimating = false; this.options.onAfterChange( $slide, this.current ); }
Finally, the plugin offers several public methods which one can call to trigger specific actions (navigation, pause the slideshow etc..)
// public method: adds more slides to the slider add : function( $slides, callback ) { this.$slides = this.$slides.add( $slides ); var self = this; $slides.each( function( i ) { var $slide = $( this ), // vertical || horizontal orientation = $slide.data( 'orientation' ); $slide.hide().addClass( 'sl-slide-' + orientation ) .children() .wrapAll( '<div class="sl-content-wrapper" />' ) .wrapAll( '<div class="sl-content" />' ) .end() .appendTo( self.$el.find( 'div.sl-slides-wrapper' ) ); } ); this._setSize(); this.slidesCount = this.$slides.length; if ( callback ) { callback.call( $items ); } }, // public method: shows next slide next : function() { this._stopSlideshow(); this._navigate( 'next' ); }, // public method: shows previous slide previous : function() { this._stopSlideshow(); this._navigate( 'prev' ); }, // public method: goes to a specific slide jump : function( pos ) { pos -= 1; if( pos === this.current || pos >= this.slidesCount || pos < 0 ) { return false; } this._stopSlideshow(); this._navigate( pos > this.current ? 'next' : 'prev', pos ); }, // public method: starts the slideshow // any call to next(), previous() or jump() will stop the slideshow play : function() { if( !this.isPlaying ) { this.isPlaying = true; this._navigate( 'next' ); this.options.autoplay = true; this._startSlideshow(); } }, // public method: pauses the slideshow pause : function() { if( this.isPlaying ) { this._stopSlideshow(); } }, // public method: check if isAnimating is true isActive : function() { return this.isAnimating; }, // publicc methos: destroys the slicebox instance destroy : function( callback ) { this._destroy( callback ); }
And that’s it! I hope you enjoyed this tutorial and find it useful!
I re-write for renew congrats and for asking you to solve my problem:
i want to set in this demo page ( http://expressodesign.it/sod/screen_transit.html ) the top nav bar linked to each slide.
Every top nav element must be linked to relative slide.
which code i must change?
the javascript is based on “next-prev” concept.
please help me
thanks a lot in advance
Peter
Hello Peter,
Did you managed to get a menu working in this example?
Please, let us know. Thank you!!!
Wow thats an awesome effect and you are one of the best Web Designer with great control over jquery and css3 🙂
Hi!
I’d suggest to modify script a bit:
line 88 of jquery.slitslider.js:
var $win = (this.options.fullScreen)?$( window ):this.$slider.parent();
This will give us to have possibility to use parent element if we don’t want script work full screen.
Initializing could be:
$( '#photo').slitslider({fullScreen:false});
Then parent of my #photo element has relative position with fixed width and height.
Thanks.
Might it be possible to have a quote selector, with simple, left-right/up-down navigation arrows (maybe with a simple, fade animation) to change between quotes on each page, without resetting your choice of quote when you change pages?
And perhaps when you change quotes, the image can also change?
Would it possible to replace the animal font character with an image? I also wanted to use this hover effect, but with just a simple text (just the italized body): http://tympanus.net/Tutorials/OriginalHoverEffects/index6.html.
Excellent tutorial! I wonder how can I target/link slides? say when you are looking at the demo page and you can see CODROP link bar at top. If you were to put links there targeting to each slides? I see Denis’s suggestion, but I’m not clear.
Great plugin! Is there a way to invoke a callback when the animation (horizontal) has been processed?
Marco, take a look at http://tympanus.net/Tutorials/FullscreenSlitSlider/js/testing/jquery.slitslider.js
Then as an example you could do something like:
$( ‘#sl-slider’ ).slitslider( {
onStart : function( orientation ) {
console.log( ‘start..’ + orientation );
},
onEnd : function( orientation ) {
console.log( ‘end..’ + orientation );
}
} );
Hope it helps! Cheers, ML
Great job! but doesnt work with Internet Explorer… 🙁
This is really cool. Do you have a fix for Internet Explorer? It also “flickers” the page when using full-screen in Safari. Is there a fix for this bug?
This is great! 🙂 Have a question though – what part of the code should be modified to add navigation to this? What code should I add to allow users to navigate to a specific slide?
Woow WTF I’m impressed! This is da bomb! Very nice and smooth transitions. CSS3-magic. Now a bit of party-poopers-mode; how does IE8 and 9 Handle this?
It may be possible to do it with shims. For the nth-child property you can just include Selectivizr, and jQuery has the .before() and .after() properties, which perform the same function as the :before and :after psuedo-selectors. I haven’t tried to mod this code for these workarounds, but it seems entirely possible.
amazing what we can do with these technologies, thanks for the tutorial
Hi, thank you very much for this tutorial, this is awesome.
I was wondering if maybe we could add a nav menu instead (or with) of the prev/next arrow ?
Thank for your help !
Hi,
Stunning effect, but i havoc been looking of days to adapt it with a menu… unsuccessfully……..
May be you have a clue for this?
Cheers,
Thank you for your work ^_^
Hey Mary! How do you get a scroll bar to show up on this if the quote you’re using is much longer than just two to three lines? And also how do you change the quote box area to be wider?
I forgot to mention, how do you also make it Responsive? I’d love if this layout can be viewed on mobile phones/smartphones/iPads and tablets
is there a way to use a menu instead of the next and previous button?
please help.
Has anybody figured out a menu instead of the arrow navigation?
Hi everyone, for people struggling with customising the menu, you have to replace the following in the original code:
if( this.slidesCount > 1 ) { // navigate "in" or "out" this.$slider.find( 'nav > span.sl-prev' ).on( 'click.slitslider', function( event ) { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'out' ); } ).end().find( 'nav > span.sl-next' ).on( 'click.slitslider', function( event ) { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'in' ); } ); }
With a very quick workaround as follows. It’s cross-browser compatible, just maybe a bit hacky and messy lol.
First, create your menu objects and give them each a unique class (note: this only works for next and previous). Then, paste the following code into the jquery.slitslider.js document.
if( this.slidesCount > 1 ) { // navigate "in" or "out" $(".prev").click(function () { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'out' ); } ).end().find( 'html body div.container div.backgroundNav div.next a' ).on( 'click.slitslider', function( event ) { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'in' ); } ); }
Ensure that “.prev” and “html body div.container div.backgroundNav div.next a” relate to your own code. “.prev” in this example relates to my own previous button class. The latter is just a copy and paste from Firebug by right-clicking the element and selecting “Copy CSS Path”. There’s probably much neater ways of doing it but this was the workaround I’ve been playing around with.
Cheers.
Oh and I forgot to mention, you’ll also need to remove this section:
// add navigation if( this.slidesCount > 1 ) { this.$slider.append( 'PreviousNext' ); }
Or it will still display the original navigation 🙂
is there any way to insert images into this so i could use a lightbox within this site?
please reply asap as i need to know quite quick
thank you to everyone that has made this and that would help me with my problem
best regards
alex michael
All you would need to do is put the images within the content areas of each section but I’m not sure how a Lightbox could be implemented… Sorry I can’t be of any more help.
Im having problems on chrome Version 21.0.1180.57 on my mac running on mountain lion, the image stays static on the right and does not move. But it works well for me on safari and firefox.
Does it work well with the demo above? If so it’s possible you don’t have one of the jquery libraries or other essential files linked up correctly :). I could be wrong of course.
Hi ML, Andrew,
Anyone know of a fix for chrome version 21.0.1180.57? The image stays static on right side and does not move – works however on safari and firefox as well as ipad.
excellent slider.
Great slider, however, I`m the one amongst menu who is trying to add menu to it. I followed your instructions Andrew, but they are not very clear. I changed the code, created menu and added unique classes to each menu element/link. Can you please be more descriptive about this part:
“Ensure that “.prev” and “html body div.container div.backgroundNav div.next a” relate to your own code. “.prev” in this example relates to my own previous button class. The latter is just a copy and paste from Firebug by right-clicking the element and selecting “Copy CSS Path”. There’s probably much neater ways of doing it but this was the workaround I’ve been playing around with.”
Thank you very much!
I have the same problem of Will.
The slider, in my site and in this demo, have a problem with chrome version 21.0.1180.57.
The image stays static on right side and does not move.
Anyone have fixed this bug?
Thank you very much!
hello, the demo have some problem on chrome! Have you some advice?
Hi, thanks for your feedback, we’ll take a look into this! Cheers, ML
The demo is updated, let me know if you still experience any problems in Chrome. Thanks, ML
Hi! Now the demo is ok!
What changes you have made?
Thank you!
You have done a great work!
This is… AWESOME!
Hi there,
I’m using this tutorial, but I wanna use multiple slitslider in my HTML.
If I call them in my javascript function, none of them work.
Can you help me out with that?
Hello,
I am trying to implement this into a website and I have a couple of customizing questions.
1. I need it to be mouse drag-able, if possible?
2. I need to remove the left arrow and after it slides to the next slide, I need to remove the right arrow.
Please let me know if these customizations can be done.
I really love this slider, GREAT WORK!
UPDATE: I found how to remove the left arrow, but still looking into the mouse draggabilty. Anyone got an idea on how to implement it?
Hi, just a simple question , how do you change the animal icon on the different slides ?
Hello, how to change font ‘animal ‘ icon for to put picture?
thx..
Any luck on adding in an actual menu/navigation. All of my efforts are failing…
I’m also looking for this function !
This is awesome. but, would u help me? how I can change the picture?
I want to know too!!
If you’re talking about the animals in the first demo, those are not images. They are actually fonts. If you look at demo.css you will see a font-face callout for “AnimalsNormal”. To change the displayed animal, simply change the data-icon value to your liking in
Hi Mary Lou
Great Work of Art. If I wanted to change the images, How would I do that?
The demo doesn’t work on my computer; using an iMac v27″ with Google Chrome. It just stands still.
I would ask how one would bind the slide transition to left/right keys on keyboard?
You should open jquery.slitslider.js find
$( window ).on( 'smartresize.slitslider', function( event ) { // update window size _self._getWinSize(); _self._setSize(); } );
and below that add
$(window).keydown(function (e) { var keyCode = e.keyCode || e.which, arrow = {left: 37, right: 39 }; switch (keyCode) { case arrow.left: if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'out' ); break; case arrow.right: if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'in' ); break; } });
Karolis – Sometime during my life time there shell be a monument erected for thee and 1000 gallons of extra virgin oil will be sacrificed in thy name!
PS: Thank you, that really helped out mate 🙂
hello, really beautiful script. But I have problems. Explorer will not start on the animation of the slide. Also more on chrome can not see the images I uploaded instead of colors. thanks
Something seems to have changed the last few days. As this Script has stopped working.
That’s true! We will soon update the script 🙂 Cheers, ML
Lovely! Works great on Safari, but not on latest FF (16.0.1) for some reason.
For FF, we have to update “jquery.transit.min.js” with “jquery.transit-0.1.3.min.js”
Enjoy !
Updated! ML
Great slider. Definitely going to use it in my next project.
So beautiful! Haven’t tried it yet! If I have a client and actually used this I am going to donate a significant amount… hmn no donation button.
Hey great tutorial!! so nice, how do you change the pictures though?
Hi, i am interested with this tutorial and i’m pleasant with its effect! I was wondering how can i put this slider in my homepage (i am using wordpress), i mean, what files should i edit (header.php or what?), also where do i put javascript file? Thanks for any explanation
yuginta – I’m working on a theme for wordpress (to be released for free ofc with all credits where the credits are due). It shall be released sometimes by the beginning of the next week. I’ll publish the link here 🙂
Hey Dorian – did you ever manage to do the WordPress theme? I too would love that!
Love the second demo slider and the text animations… but not a big fan of the slicing effect. Anybody out there know how I can just make them fade? Great article by the way… would love to use this slider sans the slices. Cheers!
this doesn’t work on ubuntu chrome & opera. if anyone can help, please do.
Nice work, looks great. Bit of feedback for you: when I checked the demo using iOS the vertical transition is buggy, but the reverse vertical transition works fine, i.e, when you press a button to the left on the second demo.