├── README.md ├── css ├── component.css ├── demo.css └── normalize.css ├── fonts └── codropsicons │ ├── codropsicons.eot │ ├── codropsicons.svg │ ├── codropsicons.ttf │ ├── codropsicons.woff │ └── license.txt ├── img ├── 1.jpg ├── 2.jpg ├── 3.jpg └── 4.jpg ├── index.html ├── index2.html ├── index3.html └── js ├── boxesFx.js ├── classie.js └── modernizr.custom.js /README.md: -------------------------------------------------------------------------------- 1 | Four Boxes Slideshow 2 | ========= 3 | 4 | A tutorial on how to recreate the four panel background image slideshow seen on Atelier Serge Thoroval's website. 5 | 6 | [Article on Codrops](http://tympanus.net/codrops/?p=19242) 7 | 8 | [Demo](http://tympanus.net/Tutorials/FourBoxes/) 9 | 10 | Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". 11 | 12 | Images used in demo are made with Mockups made by [Mockuuups.com](http://www.mockuuups.com/) 13 | 14 | Read more here: [License](http://tympanus.net/codrops/licensing/) 15 | 16 | [© Codrops 2014](http://www.codrops.com) 17 | -------------------------------------------------------------------------------- /css/component.css: -------------------------------------------------------------------------------- 1 | html, body, .container { 2 | height: 100%; 3 | } 4 | 5 | .js .boxgallery, 6 | .js .boxgallery div { 7 | position: absolute; 8 | } 9 | 10 | .js .boxgallery, 11 | .bg-tile, 12 | .bg-img { 13 | overflow: hidden; 14 | } 15 | 16 | .js .boxgallery, 17 | .js .panel { 18 | top: 0; 19 | left: 0; 20 | width: 100%; 21 | height: 100%; 22 | } 23 | 24 | .panel { 25 | z-index: 0; 26 | -webkit-perspective: 1200px; 27 | perspective: 1200px; 28 | } 29 | 30 | .bg-tile { 31 | width: 50%; 32 | height: 50%; 33 | } 34 | 35 | .bg-tile:nth-child(2), 36 | .bg-tile:nth-child(4) { 37 | left: 50%; 38 | } 39 | 40 | .bg-tile:nth-child(3), 41 | .bg-tile:nth-child(4) { 42 | top: 50%; 43 | } 44 | 45 | .bg-img { 46 | width: 100%; 47 | height: 100%; 48 | background: #999; 49 | } 50 | 51 | .bg-img img { 52 | position: absolute; 53 | display: block; 54 | height: 200%; 55 | } 56 | 57 | @media screen and (min-aspect-ratio: 1280/850) { 58 | .bg-img img { 59 | width: 200%; 60 | height: auto; 61 | } 62 | } 63 | 64 | .bg-tile:nth-child(2) .bg-img img, 65 | .bg-tile:nth-child(4) .bg-img img { 66 | left: -100%; 67 | } 68 | 69 | .bg-tile:nth-child(3) .bg-img img, 70 | .bg-tile:nth-child(4) .bg-img img { 71 | top: -100%; 72 | } 73 | 74 | /* Navigation Arrow */ 75 | .boxgallery > nav span { 76 | position: absolute; 77 | top: 50%; 78 | z-index: 1000; 79 | display: block; 80 | width: 100px; 81 | height: 100px; 82 | outline: none; 83 | text-align: left; 84 | cursor: pointer; 85 | -webkit-transform: translateY(-50%); 86 | transform: translateY(-50%); 87 | } 88 | 89 | .boxgallery > nav span.prev { 90 | left: 0; 91 | } 92 | 93 | .boxgallery > nav span.next { 94 | right: 0; 95 | } 96 | 97 | .boxgallery > nav i { 98 | position: relative; 99 | display: block; 100 | width: 100%; 101 | height: 100%; 102 | } 103 | 104 | .boxgallery > nav span::before, 105 | .boxgallery > nav span::after, 106 | .boxgallery > nav i::before, 107 | .boxgallery > nav i::after { 108 | position: absolute; 109 | left: 50%; 110 | width: 3px; 111 | height: 50%; 112 | outline: 1px solid transparent; 113 | background: #dbccd0; 114 | content: ''; 115 | -webkit-transition: -webkit-transform 0.3s; 116 | transition: transform 0.3s; 117 | -webkit-backface-visibility: hidden; 118 | backface-visibility: hidden; 119 | } 120 | 121 | .boxgallery > nav i::before, 122 | .boxgallery > nav i::after { 123 | z-index: 100; 124 | height: 0; 125 | background: #fff; 126 | -webkit-transition: height 0.3s, -webkit-transform 0.3s; 127 | transition: height 0.3s, transform 0.3s; 128 | } 129 | 130 | .boxgallery > nav span::before, 131 | .boxgallery > nav i::before { 132 | top: 50%; 133 | -webkit-transform: translateX(-50%) rotate(-135deg); 134 | transform: translateX(-50%) rotate(-135deg); 135 | -webkit-transform-origin: 50% 0%; 136 | transform-origin: 50% 0%; 137 | } 138 | 139 | .boxgallery > nav span.next::before, 140 | .boxgallery > nav span.next i::before { 141 | -webkit-transform: translateX(-50%) rotate(135deg); 142 | transform: translateX(-50%) rotate(135deg); 143 | -webkit-transform-origin: 50% 0%; 144 | transform-origin: 50% 0%; 145 | } 146 | 147 | .boxgallery > nav span::after, 148 | .boxgallery > nav i::after { 149 | top: 50%; 150 | -webkit-transform: translateX(-50%) rotate(-45deg); 151 | transform: translateX(-50%) rotate(-45deg); 152 | -webkit-transform-origin: 0 0; 153 | transform-origin: 0 0; 154 | } 155 | 156 | .boxgallery > nav span.next::after, 157 | .boxgallery > nav span.next i::after { 158 | -webkit-transform: translateX(-50%) rotate(45deg); 159 | transform: translateX(-50%) rotate(45deg); 160 | -webkit-transform-origin: 100% 0%; 161 | transform-origin: 100% 0%; 162 | } 163 | 164 | .no-touch .boxgallery > nav span:hover i::before, 165 | .no-touch .boxgallery > nav span:hover i::after { 166 | height: 50%; 167 | } 168 | 169 | .no-touch .boxgallery > nav span:hover::before, 170 | .no-touch .boxgallery > nav span:hover i::before { 171 | -webkit-transform: translateX(-50%) rotate(-125deg); 172 | transform: translateX(-50%) rotate(-125deg); 173 | } 174 | 175 | .no-touch .boxgallery > nav span.next:hover::before, 176 | .no-touch .boxgallery > nav span.next:hover i::before { 177 | -webkit-transform: translateX(-50%) rotate(125deg); 178 | transform: translateX(-50%) rotate(125deg); 179 | } 180 | 181 | .no-touch .boxgallery > nav span:hover::after, 182 | .no-touch .boxgallery > nav span:hover i::after { 183 | -webkit-transform: translateX(-50%) rotate(-55deg); 184 | transform: translateX(-50%) rotate(-55deg); 185 | } 186 | 187 | .no-touch .boxgallery > nav span.next:hover::after, 188 | .no-touch .boxgallery > nav span.next:hover i::after { 189 | -webkit-transform: translateX(-50%) rotate(55deg); 190 | transform: translateX(-50%) rotate(55deg); 191 | } 192 | 193 | /* Transitions and individual delays/effects */ 194 | /* The "active" class is given to the panel that is coming */ 195 | 196 | .panel.current { 197 | z-index: 2; 198 | } 199 | 200 | .panel.active { 201 | z-index: 1; 202 | } 203 | 204 | .panel.current .bg-img { 205 | -webkit-transition: -webkit-transform 1.1s ease-in-out; 206 | transition: transform 1.1s ease-in-out; 207 | } 208 | 209 | .boxgallery[data-effect="effect-1"] .panel.active .bg-tile, 210 | .boxgallery[data-effect="effect-2"] .panel.active .bg-tile { 211 | -webkit-animation: scaleDown 1.1s ease-in-out; 212 | animation: scaleDown 1.1s ease-in-out; 213 | } 214 | 215 | @-webkit-keyframes scaleDown { 216 | from { -webkit-transform: translate3d(0,0,380px); transform: translate3d(0,0,380px); } 217 | to { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } 218 | } 219 | 220 | @keyframes scaleDown { 221 | from { -webkit-transform: translate3d(0,0,380px); transform: translate3d(0,0,380px); } 222 | to { -webkit-transform: translate3d(0,0,0); transform: translate3d(0,0,0); } 223 | } 224 | 225 | /* Variation 2 */ 226 | .boxgallery[data-effect="effect-2"] .panel.current .bg-img { 227 | -webkit-transition: -webkit-transform 0.9s cubic-bezier(0.7,0,0.3,1); 228 | transition: transform 0.9s cubic-bezier(0.7,0,0.3,1); 229 | } 230 | 231 | .boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(2) .bg-img { 232 | -webkit-transition-delay: 0.15s; 233 | transition-delay: 0.15s; 234 | } 235 | 236 | .boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(3) .bg-img { 237 | -webkit-transition-delay: 0.3s; 238 | transition-delay: 0.3s; 239 | } 240 | 241 | .boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(4) .bg-img { 242 | -webkit-transition-delay: 0.45s; 243 | transition-delay: 0.45s; 244 | } 245 | 246 | /* Variation 3 */ 247 | .boxgallery[data-effect="effect-3"] .panel::after { 248 | position: absolute; 249 | width: 100%; 250 | height: 100%; 251 | background: rgba(0,0,0,0.8); 252 | content: ''; 253 | -webkit-transition: opacity 1.1s ease-in-out; 254 | transition: opacity 1.1s ease-in-out; 255 | } 256 | 257 | .boxgallery[data-effect="effect-3"] .panel.current::after, 258 | .boxgallery[data-effect="effect-3"] .panel.active::after { 259 | opacity: 0; 260 | } 261 | 262 | .boxgallery[data-effect="effect-3"] .panel.current::after { 263 | -webkit-transition: none; 264 | transition: none; 265 | } 266 | 267 | .boxgallery[data-effect="effect-3"] .panel.current .bg-img { 268 | -webkit-transition: -webkit-transform 1.1s cubic-bezier(0.7,0,0.3,1); 269 | transition: transform 1.1s cubic-bezier(0.7,0,0.3,1); 270 | } 271 | 272 | .boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(2) .bg-img { 273 | -webkit-transition-delay: 0.15s; 274 | transition-delay: 0.15s; 275 | } 276 | 277 | .boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(3) .bg-img { 278 | -webkit-transition-delay: 0.3s; 279 | transition-delay: 0.3s; 280 | } 281 | 282 | .boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(4) .bg-img { 283 | -webkit-transition-delay: 0.45s; 284 | transition-delay: 0.45s; 285 | } 286 | 287 | @media screen and (max-width: 380px) { 288 | .boxgallery > nav span { 289 | width: 50px; 290 | height: 50px; 291 | } 292 | } -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-weight: normal; 3 | font-style: normal; 4 | font-family: 'codropsicons'; 5 | src:url('../fonts/codropsicons/codropsicons.eot'); 6 | src:url('../fonts/codropsicons/codropsicons.eot?#iefix') format('embedded-opentype'), 7 | url('../fonts/codropsicons/codropsicons.woff') format('woff'), 8 | url('../fonts/codropsicons/codropsicons.ttf') format('truetype'), 9 | url('../fonts/codropsicons/codropsicons.svg#codropsicons') format('svg'); 10 | } 11 | 12 | *, *:after, *:before { -webkit-box-sizing: border-box; box-sizing: border-box; } 13 | .clearfix:before, .clearfix:after { content: ''; display: table; } 14 | .clearfix:after { clear: both; } 15 | 16 | body { 17 | background: #333; 18 | color: #fff; 19 | font-weight: 200; 20 | font-size: 1em; 21 | font-family: 'Raleway', 'Arial', sans-serif; 22 | } 23 | 24 | a { 25 | color: #fff; 26 | text-decoration: none; 27 | outline: none; 28 | font-weight: 600; 29 | } 30 | 31 | a:hover, a:focus { 32 | color: #debcc3; 33 | } 34 | 35 | section { 36 | padding: 1em; 37 | text-align: center; 38 | } 39 | 40 | /* Header */ 41 | .codrops-header { 42 | z-index: 1000; 43 | position: absolute; 44 | top: 50%; 45 | left: 50%; 46 | text-align: center; 47 | max-width: 500px; 48 | -webkit-transform: translate(-50%,-50%); 49 | transform: translate(-50%,-50%); 50 | -webkit-backface-visibility: hidden; 51 | backface-visibility: hidden; 52 | } 53 | 54 | .codrops-header h1 { 55 | margin: 0; 56 | font-weight: 200; 57 | font-size: 3em; 58 | line-height: 1; 59 | } 60 | 61 | .codrops-header h1 span { 62 | display: block; 63 | padding: 0.5em 0 0.6em 0.1em; 64 | font-size: 40%; 65 | line-height: 1.2; 66 | opacity: 0.7; 67 | } 68 | 69 | /* To Navigation Style */ 70 | .codrops-top { 71 | width: 100%; 72 | text-transform: uppercase; 73 | font-weight: 400; 74 | font-size: 0.69em; 75 | line-height: 2.2; 76 | position: relative; 77 | z-index: 2000; 78 | } 79 | 80 | .codrops-top a { 81 | display: inline-block; 82 | padding: 0.3em 0.7em; 83 | text-decoration: none; 84 | letter-spacing: 1px; 85 | margin: 5px; 86 | } 87 | 88 | .codrops-top span.right { 89 | float: right; 90 | } 91 | 92 | .codrops-top span.right a { 93 | display: block; 94 | float: left; 95 | } 96 | 97 | .codrops-icon:before { 98 | margin: 0 4px; 99 | text-transform: none; 100 | font-weight: normal; 101 | font-style: normal; 102 | font-variant: normal; 103 | font-family: 'codropsicons'; 104 | line-height: 1; 105 | speak: none; 106 | -webkit-font-smoothing: antialiased; 107 | } 108 | 109 | .codrops-icon-drop:before { 110 | content: "\e001"; 111 | } 112 | 113 | .codrops-icon-prev:before { 114 | content: "\e004"; 115 | } 116 | 117 | /* Demo Buttons Style */ 118 | .codrops-demos { 119 | padding-top: 2em; 120 | font-size: 0.8em; 121 | } 122 | 123 | .codrops-demos a { 124 | display: inline-block; 125 | margin: 0.5em; 126 | padding: 0.7em 1.1em; 127 | outline: none; 128 | border: 2px solid #fff; 129 | text-decoration: none; 130 | text-transform: uppercase; 131 | letter-spacing: 1px; 132 | width: 165px; 133 | } 134 | 135 | .codrops-demos a:hover, 136 | .codrops-demos a.current-demo, 137 | .codrops-demos a.current-demo:hover { 138 | color: #debcc3; 139 | border-color: #debcc3; 140 | } 141 | 142 | @media screen and (max-width: 25em) { 143 | 144 | .codrops-icon span { 145 | display: none; 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden]{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/fonts/codropsicons/codropsicons.eot -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/fonts/codropsicons/codropsicons.ttf -------------------------------------------------------------------------------- /fonts/codropsicons/codropsicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/fonts/codropsicons/codropsicons.woff -------------------------------------------------------------------------------- /fonts/codropsicons/license.txt: -------------------------------------------------------------------------------- 1 | Icon Set: Font Awesome -- http://fortawesome.github.com/Font-Awesome/ 2 | License: SIL -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | 4 | 5 | Icon Set: Eco Ico -- http://dribbble.com/shots/665585-Eco-Ico 6 | License: CC0 -- http://creativecommons.org/publicdomain/zero/1.0/ -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/img/1.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/img/2.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/img/3.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/FourBoxes/f90ea18ca5ecfe016b98c17fe695a7cedcb9fd24/img/4.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Four Boxes Slideshow | Demo 1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | Previous Demo 23 | Back to the Codrops Article 24 |
25 |
26 |
Image 1
27 |
Image 2
28 |
Image 3
29 |
Image 4
30 |
31 |
32 |

Four Boxes Slideshow Recreating the background image slideshow seen on Atelier Serge Thoroval's website

33 | 38 |
39 |
40 | 41 | 42 | 45 | 46 | -------------------------------------------------------------------------------- /index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Four Boxes Slideshow | Demo 2 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | Previous Demo 23 | Back to the Codrops Article 24 |
25 |
26 |
Image 3
27 |
Image 4
28 |
Image 1
29 |
Image 2
30 |
31 |
32 |

Four Boxes Slideshow Recreating the background image slideshow seen on Atelier Serge Thoroval's website

33 | 38 |
39 |
40 | 41 | 42 | 45 | 46 | -------------------------------------------------------------------------------- /index3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Four Boxes Slideshow | Demo 3 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 |
22 | Previous Demo 23 | Back to the Codrops Article 24 |
25 |
26 |
Image 2
27 |
Image 3
28 |
Image 1
29 |
Image 4
30 |
31 |
32 |

Four Boxes Slideshow Recreating the background image slideshow seen on Atelier Serge Thoroval's website

33 | 38 |
39 |
40 | 41 | 42 | 45 | 46 | -------------------------------------------------------------------------------- /js/boxesFx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * boxesFx.js v1.0.0 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2014, Codrops 9 | * http://www.codrops.com 10 | */ 11 | ;( function( window ) { 12 | 13 | 'use strict'; 14 | 15 | // based on http://responsejs.com/labs/dimensions/ 16 | function getViewport(axis) { 17 | var client, inner; 18 | if( axis === 'x' ) { 19 | client = docElem['clientWidth']; 20 | inner = window['innerWidth']; 21 | } 22 | else if( axis === 'y' ) { 23 | client = docElem['clientHeight']; 24 | inner = window['innerHeight']; 25 | } 26 | 27 | return client < inner ? inner : client; 28 | } 29 | 30 | var docElem = window.document.documentElement, 31 | transEndEventNames = { 32 | 'WebkitTransition': 'webkitTransitionEnd', 33 | 'MozTransition': 'transitionend', 34 | 'OTransition': 'oTransitionEnd', 35 | 'msTransition': 'MSTransitionEnd', 36 | 'transition': 'transitionend' 37 | }, 38 | transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], 39 | support = { transitions : Modernizr.csstransitions }, 40 | win = { width : getViewport('x'), height : getViewport('y') }; 41 | 42 | function extend( a, b ) { 43 | for( var key in b ) { 44 | if( b.hasOwnProperty( key ) ) { 45 | a[key] = b[key]; 46 | } 47 | } 48 | return a; 49 | } 50 | 51 | function BoxesFx( el, options ) { 52 | this.el = el; 53 | this.options = extend( {}, this.options ); 54 | extend( this.options, options ); 55 | this._init(); 56 | } 57 | 58 | BoxesFx.prototype.options = {} 59 | 60 | BoxesFx.prototype._init = function() { 61 | // set transforms configuration 62 | this._setTransforms(); 63 | // which effect 64 | this.effect = this.el.getAttribute( 'data-effect' ) || 'effect-1'; 65 | // check if animating 66 | this.isAnimating = false; 67 | // the panels 68 | this.panels = [].slice.call( this.el.querySelectorAll( '.panel' ) ); 69 | // total number of panels (4 for this demo) 70 | //this.panelsCount = this.panels.length; 71 | this.panelsCount = 4; 72 | // current panel´s index 73 | this.current = 0; 74 | classie.add( this.panels[0], 'current' ); 75 | // replace image with 4 divs, each including the image 76 | var self = this; 77 | this.panels.forEach( function( panel ) { 78 | var img = panel.querySelector( 'img' ), imgReplacement = ''; 79 | for( var i = 0; i < self.panelsCount; ++i ) { 80 | imgReplacement += '
' 81 | } 82 | panel.removeChild( img ); 83 | panel.innerHTML = imgReplacement + panel.innerHTML; 84 | } ); 85 | // add navigation element 86 | this.nav = document.createElement( 'nav' ); 87 | this.nav.innerHTML = ''; 88 | this.el.appendChild( this.nav ); 89 | // initialize events 90 | this._initEvents(); 91 | } 92 | 93 | // set the transforms per effect 94 | // we have defined both the next and previous action transforms for each panel 95 | BoxesFx.prototype._setTransforms = function() { 96 | this.transforms = { 97 | 'effect-1' : { 98 | 'next' : [ 99 | 'translate3d(0, ' + (win.height/2+10) + 'px, 0)', // transforms for 1 panel 100 | 'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', // transforms for 2 panel 101 | 'translate3d(' + (win.width/2+10) + 'px, 0, 0)', // transforms for 3 panel 102 | 'translate3d(0, -' + (win.height/2+10) + 'px, 0)' // transforms for 4 panel 103 | ], 104 | 'prev' : [ 105 | 'translate3d(' + (win.width/2+10) + 'px, 0, 0)', 106 | 'translate3d(0, ' + (win.height/2+10) + 'px, 0)', 107 | 'translate3d(0, -' + (win.height/2+10) + 'px, 0)', 108 | 'translate3d(-' + (win.width/2+10) + 'px, 0, 0)' 109 | ] 110 | }, 111 | 'effect-2' : { 112 | 'next' : [ 113 | 'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', 114 | 'translate3d(' + (win.width/2+10) + 'px, 0, 0)', 115 | 'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', 116 | 'translate3d(' + (win.width/2+10) + 'px, 0, 0)' 117 | ], 118 | 'prev' : [ 119 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)', 120 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)', 121 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)', 122 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)' 123 | ] 124 | }, 125 | 'effect-3' : { 126 | 'next' : [ 127 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)', 128 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)', 129 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)', 130 | 'translate3d(0,' + (win.height/2+10) + 'px, 0)' 131 | ], 132 | 'prev' : [ 133 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)', 134 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)', 135 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)', 136 | 'translate3d(0,-' + (win.height/2+10) + 'px, 0)' 137 | ] 138 | } 139 | }; 140 | } 141 | 142 | BoxesFx.prototype._initEvents = function() { 143 | var self = this, navctrls = this.nav.children; 144 | // previous action 145 | navctrls[0].addEventListener( 'click', function() { self._navigate('prev') } ); 146 | // next action 147 | navctrls[1].addEventListener( 'click', function() { self._navigate('next') } ); 148 | // window resize 149 | window.addEventListener( 'resize', function() { self._resizeHandler(); } ); 150 | } 151 | 152 | // goto next or previous slide 153 | BoxesFx.prototype._navigate = function( dir ) { 154 | if( this.isAnimating ) return false; 155 | this.isAnimating = true; 156 | 157 | var self = this, currentPanel = this.panels[ this.current ]; 158 | 159 | if( dir === 'next' ) { 160 | this.current = this.current < this.panelsCount - 1 ? this.current + 1 : 0; 161 | } 162 | else { 163 | this.current = this.current > 0 ? this.current - 1 : this.panelsCount - 1; 164 | } 165 | 166 | // next panel to be shown 167 | var nextPanel = this.panels[ this.current ]; 168 | // add class active to the next panel to trigger its animation 169 | classie.add( nextPanel, 'active' ); 170 | // apply the transforms to the current panel 171 | this._applyTransforms( currentPanel, dir ); 172 | 173 | // let´s track the number of transitions ended per panel 174 | var cntTransTotal = 0, 175 | 176 | // transition end event function 177 | onEndTransitionFn = function( ev ) { 178 | if( ev && !classie.has( ev.target, 'bg-img' ) ) return false; 179 | 180 | // return if not all panel transitions ended 181 | ++cntTransTotal; 182 | if( cntTransTotal < self.panelsCount ) return false; 183 | 184 | if( support.transitions ) { 185 | this.removeEventListener( transEndEventName, onEndTransitionFn ); 186 | } 187 | 188 | // remove current class from current panel and add it to the next one 189 | classie.remove( currentPanel, 'current' ); 190 | classie.add( nextPanel, 'current' ); 191 | // reset transforms for the currentPanel 192 | self._resetTransforms( currentPanel ); 193 | // remove class active 194 | classie.remove( nextPanel, 'active' ); 195 | self.isAnimating = false; 196 | }; 197 | 198 | if( support.transitions ) { 199 | currentPanel.addEventListener( transEndEventName, onEndTransitionFn ); 200 | } 201 | else { 202 | onEndTransitionFn(); 203 | } 204 | } 205 | 206 | BoxesFx.prototype._applyTransforms = function( panel, dir ) { 207 | var self = this; 208 | [].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile, pos ) { 209 | tile.style.WebkitTransform = self.transforms[self.effect][dir][pos]; 210 | tile.style.transform = self.transforms[self.effect][dir][pos]; 211 | } ); 212 | } 213 | 214 | BoxesFx.prototype._resetTransforms = function( panel ) { 215 | [].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile ) { 216 | tile.style.WebkitTransform = 'none'; 217 | tile.style.transform = 'none'; 218 | } ); 219 | } 220 | 221 | BoxesFx.prototype._resizeHandler = function() { 222 | var self = this; 223 | function delayed() { 224 | self._resize(); 225 | self._resizeTimeout = null; 226 | } 227 | if ( this._resizeTimeout ) { 228 | clearTimeout( this._resizeTimeout ); 229 | } 230 | this._resizeTimeout = setTimeout( delayed, 50 ); 231 | } 232 | 233 | BoxesFx.prototype._resize = function() { 234 | win.width = getViewport('x'); 235 | win.height = getViewport('y'); 236 | this._setTransforms(); 237 | } 238 | 239 | // add to global namespace 240 | window.BoxesFx = BoxesFx; 241 | 242 | } )( window ); 243 | -------------------------------------------------------------------------------- /js/classie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * classie - class helper functions 3 | * from bonzo https://github.com/ded/bonzo 4 | * 5 | * classie.has( elem, 'my-class' ) -> true/false 6 | * classie.add( elem, 'my-new-class' ) 7 | * classie.remove( elem, 'my-unwanted-class' ) 8 | * classie.toggle( elem, 'my-class' ) 9 | */ 10 | 11 | /*jshint browser: true, strict: true, undef: true */ 12 | /*global define: false */ 13 | 14 | ( function( window ) { 15 | 16 | 'use strict'; 17 | 18 | // class helper functions from bonzo https://github.com/ded/bonzo 19 | 20 | function classReg( className ) { 21 | return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); 22 | } 23 | 24 | // classList support for class management 25 | // altho to be fair, the api sucks because it won't accept multiple classes at once 26 | var hasClass, addClass, removeClass; 27 | 28 | if ( 'classList' in document.documentElement ) { 29 | hasClass = function( elem, c ) { 30 | return elem.classList.contains( c ); 31 | }; 32 | addClass = function( elem, c ) { 33 | elem.classList.add( c ); 34 | }; 35 | removeClass = function( elem, c ) { 36 | elem.classList.remove( c ); 37 | }; 38 | } 39 | else { 40 | hasClass = function( elem, c ) { 41 | return classReg( c ).test( elem.className ); 42 | }; 43 | addClass = function( elem, c ) { 44 | if ( !hasClass( elem, c ) ) { 45 | elem.className = elem.className + ' ' + c; 46 | } 47 | }; 48 | removeClass = function( elem, c ) { 49 | elem.className = elem.className.replace( classReg( c ), ' ' ); 50 | }; 51 | } 52 | 53 | function toggleClass( elem, c ) { 54 | var fn = hasClass( elem, c ) ? removeClass : addClass; 55 | fn( elem, c ); 56 | } 57 | 58 | var classie = { 59 | // full names 60 | hasClass: hasClass, 61 | addClass: addClass, 62 | removeClass: removeClass, 63 | toggleClass: toggleClass, 64 | // short names 65 | has: hasClass, 66 | add: addClass, 67 | remove: removeClass, 68 | toggle: toggleClass 69 | }; 70 | 71 | // transport 72 | if ( typeof define === 'function' && define.amd ) { 73 | // AMD 74 | define( classie ); 75 | } else { 76 | // browser global 77 | window.classie = classie; 78 | } 79 | 80 | })( window ); 81 | -------------------------------------------------------------------------------- /js/modernizr.custom.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.8.2 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-csstransitions-touch-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function z(a){j.cssText=a}function A(a,b){return z(m.join(a+";")+(b||""))}function B(a,b){return typeof a===b}function C(a,b){return!!~(""+a).indexOf(b)}function D(a,b){for(var d in a){var e=a[d];if(!C(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function E(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:B(f,"function")?f.bind(d||b):f}return!1}function F(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+o.join(d+" ")+d).split(" ");return B(b,"string")||B(b,"undefined")?D(e,b):(e=(a+" "+p.join(d+" ")+d).split(" "),E(e,b,c))}var d="2.8.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n="Webkit Moz O ms",o=n.split(" "),p=n.toLowerCase().split(" "),q={},r={},s={},t=[],u=t.slice,v,w=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},x={}.hasOwnProperty,y;!B(x,"undefined")&&!B(x.call,"undefined")?y=function(a,b){return x.call(a,b)}:y=function(a,b){return b in a&&B(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=u.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(u.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(u.call(arguments)))};return e}),q.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:w(["@media (",m.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},q.csstransitions=function(){return F("transition")};for(var G in q)y(q,G)&&(v=G.toLowerCase(),e[v]=q[G](),t.push((e[v]?"":"no-")+v));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)y(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},z(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=m,e._domPrefixes=p,e._cssomPrefixes=o,e.testProp=function(a){return D([a])},e.testAllProps=F,e.testStyles=w,e.prefixed=function(a,b,c){return b?F(a,b,c):F(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+t.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f