├── README.md ├── css ├── component.css └── demo.css ├── favicon.ico ├── fonts └── bpicons │ ├── bpicons.eot │ ├── bpicons.svg │ ├── bpicons.ttf │ ├── bpicons.woff │ └── license.txt ├── images ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg └── 6.jpg ├── index.html └── js ├── classie.js ├── main.js └── modernizr-custom.js /README.md: -------------------------------------------------------------------------------- 1 | Blueprint: Page Stack Navigation 2 | ========= 3 | 4 | A template for a simple page stack navigation based on the Dribbble shot by Ilya Kostin, Stacked navigation. 5 | 6 | [Article on Codrops](http://tympanus.net/codrops/?p=25311) 7 | 8 | [Demo](http://tympanus.net/Blueprints/PageStackNavigation/) 9 | 10 | The Blueprints are a collection of basic and minimal website concepts, components, plugins and layouts with minimal style for easy adaption and usage, or simply for inspiration. 11 | 12 | Check out all of our Blueprints [here](http://tympanus.net/codrops/category/blueprints/) 13 | 14 | Integrate or build upon it for free in your personal or commercial projects. Don't republish, redistribute or sell "as-is". 15 | 16 | Read more here: [License](http://tympanus.net/codrops/licensing/) 17 | 18 | Follow us: [Twitter](http://www.twitter.com/codrops), [Facebook](http://www.facebook.com/pages/Codrops/159107397912), [Google+](https://plus.google.com/101095823814290637419), [GitHub](https://github.com/codrops), [Pinterest](http://www.pinterest.com/codrops/) 19 | 20 | [© Codrops 2015](http://www.codrops.com) -------------------------------------------------------------------------------- /css/component.css: -------------------------------------------------------------------------------- 1 | html.js, 2 | .js body { 3 | overflow: hidden; 4 | height: 100vh; 5 | } 6 | 7 | /* Pages nav */ 8 | 9 | .pages-nav { 10 | display: -webkit-flex; 11 | display: flex; 12 | -webkit-flex-wrap: wrap; 13 | flex-wrap: wrap; 14 | -webkit-justify-content: center; 15 | justify-content: center; 16 | -webkit-align-items: center; 17 | align-items: center; 18 | padding: 20px; 19 | text-align: center; 20 | background: #0e0f0f; 21 | } 22 | 23 | .js .pages-nav { 24 | position: absolute; 25 | top: 0; 26 | left: 0; 27 | width: 100%; 28 | height: 50vh; 29 | padding: 30px; 30 | pointer-events: none; 31 | opacity: 0; 32 | background: transparent; 33 | -webkit-transition: -webkit-transform 1.2s, opacity 1.2s; 34 | transition: transform 1.2s, opacity 1.2s; 35 | -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 36 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 37 | -webkit-transform: translate3d(0, 150px, 0); 38 | transform: translate3d(0, 150px, 0); 39 | } 40 | 41 | .js .pages-nav--open { 42 | pointer-events: auto; 43 | opacity: 1; 44 | -webkit-transform: translate3d(0, 0, 0); 45 | transform: translate3d(0, 0, 0); 46 | } 47 | 48 | .pages-nav__item { 49 | width: 33%; 50 | padding: 1em; 51 | } 52 | 53 | .js .pages-nav__item { 54 | padding: 0 10%; 55 | } 56 | 57 | .pages-nav .pages-nav__item--social { 58 | width: 100%; 59 | opacity: 0; 60 | -webkit-transition: -webkit-transform 1.2s, opacity 1.2s; 61 | transition: transform 1.2s, opacity 1.2s; 62 | -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 63 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 64 | -webkit-transform: translate3d(0, 20px, 0); 65 | transform: translate3d(0, 20px, 0); 66 | } 67 | 68 | .pages-nav--open .pages-nav__item--social { 69 | opacity: 1; 70 | -webkit-transition-delay: 0.35s; 71 | transition-delay: 0.35s; 72 | -webkit-transform: translate3d(0, 0, 0); 73 | transform: translate3d(0, 0, 0); 74 | } 75 | 76 | .link { 77 | font-size: 0.85em; 78 | font-weight: bold; 79 | position: relative; 80 | letter-spacing: 1px; 81 | text-transform: uppercase; 82 | } 83 | 84 | .link:hover, 85 | .link:focus { 86 | color: #fff; 87 | } 88 | 89 | .link--page { 90 | display: block; 91 | color: #cecece; 92 | } 93 | 94 | .link--page:not(.link--faded)::before { 95 | content: ''; 96 | position: absolute; 97 | top: 100%; 98 | left: 50%; 99 | width: 30px; 100 | height: 2px; 101 | margin: 5px 0 0 -15px; 102 | background: #fff; 103 | -webkit-transition: -webkit-transform 0.3s; 104 | transition: transform 0.3s; 105 | -webkit-transform: scale3d(0, 1, 1); 106 | transform: scale3d(0, 1, 1); 107 | } 108 | 109 | .link--page:hover:before { 110 | -webkit-transform: scale3d(1, 1, 1); 111 | transform: scale3d(1, 1, 1); 112 | } 113 | 114 | .link--faded { 115 | color: #4f4f64; 116 | } 117 | 118 | .link--faded:hover, 119 | .link--faded:focus { 120 | color: #5c5edc; 121 | } 122 | 123 | .link--page.link--faded { 124 | font-size: 0.65em; 125 | } 126 | 127 | .link--social { 128 | font-size: 1.5em; 129 | margin: 0 0.75em; 130 | } 131 | 132 | .text-hidden { 133 | position: absolute; 134 | display: block; 135 | overflow: hidden; 136 | width: 0; 137 | height: 0; 138 | color: transparent; 139 | } 140 | 141 | /* Pages stack */ 142 | 143 | .js .pages-stack { 144 | z-index: 100; 145 | pointer-events: none; 146 | -webkit-perspective: 1200px; 147 | perspective: 1200px; 148 | -webkit-perspective-origin: 50% -50%; 149 | perspective-origin: 50% -50%; 150 | } 151 | 152 | .js .page { 153 | position: relative; 154 | z-index: 5; 155 | overflow: hidden; 156 | width: 100%; 157 | height: 100vh; 158 | pointer-events: auto; 159 | background: #2a2b30; 160 | box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); 161 | } 162 | 163 | .js .pages-stack--open .page { 164 | cursor: pointer; 165 | -webkit-transition: -webkit-transform 0.45s, opacity 0.45s; 166 | transition: transform 0.45s, opacity 0.45s; 167 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 168 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 169 | } 170 | 171 | .js .page--inactive { 172 | position: absolute; 173 | z-index: 0; 174 | top: 0; 175 | opacity: 0; 176 | } 177 | 178 | /* page content */ 179 | 180 | .info { 181 | font-size: 1.25em; 182 | max-width: 50%; 183 | margin-top: 1.5em; 184 | } 185 | 186 | .poster { 187 | position: absolute; 188 | bottom: 4vh; 189 | left: 60%; 190 | max-width: 100%; 191 | max-height: 80%; 192 | } 193 | 194 | /* Menu button */ 195 | 196 | .menu-button { 197 | position: absolute; 198 | z-index: 1000; 199 | top: 30px; 200 | left: 30px; 201 | width: 30px; 202 | height: 24px; 203 | padding: 0; 204 | cursor: pointer; 205 | border: none; 206 | outline: none; 207 | background: transparent; 208 | } 209 | 210 | .no-js .menu-button { 211 | display: none; 212 | } 213 | 214 | .menu-button::before, 215 | .menu-button::after, 216 | .menu-button span { 217 | background: #5f656f; 218 | } 219 | 220 | .menu-button::before, 221 | .menu-button::after { 222 | content: ''; 223 | position: absolute; 224 | top: 50%; 225 | left: 0; 226 | width: 100%; 227 | height: 2px; 228 | pointer-events: none; 229 | -webkit-transition: -webkit-transform 0.25s; 230 | transition: transform 0.25s; 231 | -webkit-transform-origin: 50% 50%; 232 | transform-origin: 50% 50%; 233 | } 234 | 235 | .menu-button span { 236 | position: absolute; 237 | left: 0; 238 | overflow: hidden; 239 | width: 100%; 240 | height: 2px; 241 | text-indent: 200%; 242 | -webkit-transition: opacity 0.25s; 243 | transition: opacity 0.25s; 244 | } 245 | 246 | .menu-button::before { 247 | -webkit-transform: translate3d(0, -10px, 0) scale3d(0.8, 1, 1); 248 | transform: translate3d(0, -10px, 0) scale3d(0.8, 1, 1); 249 | } 250 | 251 | .menu-button::after { 252 | -webkit-transform: translate3d(0, 10px, 0) scale3d(0.8, 1, 1); 253 | transform: translate3d(0, 10px, 0) scale3d(0.8, 1, 1); 254 | } 255 | 256 | .menu-button--open span { 257 | opacity: 0; 258 | } 259 | 260 | .menu-button--open::before { 261 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 262 | transform: rotate3d(0, 0, 1, 45deg); 263 | } 264 | 265 | .menu-button--open::after { 266 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 267 | transform: rotate3d(0, 0, 1, -45deg); 268 | } 269 | 270 | @media screen and (max-width: 60em) { 271 | .info { 272 | max-width: 100%; 273 | } 274 | .poster { 275 | position: relative; 276 | top: auto; 277 | left: auto; 278 | display: block; 279 | max-width: 100%; 280 | max-height: 50vh; 281 | margin: 0 0 0 50%; 282 | } 283 | .pages-nav__item { 284 | width: 50%; 285 | min-height: 20px; 286 | } 287 | .link--page { 288 | overflow: hidden; 289 | white-space: nowrap; 290 | text-overflow: ellipsis; 291 | } 292 | .link--social { 293 | margin: 0 0.1em; 294 | } 295 | } 296 | 297 | @media screen and (max-width: 40em) { 298 | .js .pages-nav { 299 | display: block; 300 | padding: 10px 20px 0 20px; 301 | text-align: left; 302 | } 303 | .js .pages-nav__item { 304 | width: 100%; 305 | padding: 4px 0; 306 | } 307 | .js .pages-nav__item--small { 308 | display: inline-block; 309 | width: auto; 310 | margin-right: 5px; 311 | } 312 | .pages-nav__item--social { 313 | font-size: 0.9em; 314 | } 315 | .menu-button { 316 | top: 15px; 317 | right: 10px; 318 | left: auto; 319 | } 320 | .info { 321 | font-size: 0.85em; 322 | } 323 | .poster { 324 | margin: 1em; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /css/demo.css: -------------------------------------------------------------------------------- 1 | /* General Blueprint Style */ 2 | 3 | @font-face { 4 | font-family: 'bpicons'; 5 | font-weight: normal; 6 | font-style: normal; 7 | src: url('../fonts/bpicons/bpicons.eot'); 8 | src: url('../fonts/bpicons/bpicons.eot?#iefix') format('embedded-opentype'), url('../fonts/bpicons/bpicons.woff') format('woff'), url('../fonts/bpicons/bpicons.ttf') format('truetype'), url('../fonts/bpicons/bpicons.svg#bpicons') format('svg'); 9 | } 10 | 11 | 12 | /* Made with http://icomoon.io/ */ 13 | 14 | 15 | /* Resets */ 16 | 17 | *, 18 | *:after, 19 | *:before { 20 | box-sizing: border-box; 21 | } 22 | 23 | 24 | /* Helper classes */ 25 | 26 | .cf:before, 27 | .cf:after { 28 | content: ' '; 29 | display: table; 30 | } 31 | 32 | .cf:after { 33 | clear: both; 34 | } 35 | 36 | 37 | /* Main styles */ 38 | 39 | body { 40 | font-family: 'Avenir Next', Avenir, 'Helvetica Neue', 'Lato', 'Segoe UI', Helvetica, Arial, sans-serif; 41 | margin: 0; 42 | color: #cecece; 43 | background: #1d1e21; 44 | -webkit-font-smoothing: antialiased; 45 | -moz-osx-font-smoothing: grayscale; 46 | } 47 | 48 | a { 49 | text-decoration: none; 50 | color: #5c5edc; 51 | outline: none; 52 | } 53 | 54 | a:hover { 55 | color: #fff; 56 | } 57 | 58 | 59 | /* Blueprint header */ 60 | 61 | .bp-header { 62 | padding: 6em 10vw 2em; 63 | } 64 | 65 | .bp-header__title { 66 | font-size: 2.125em; 67 | font-weight: 700; 68 | line-height: 1.3; 69 | margin: 0; 70 | letter-spacing: 2px; 71 | text-transform: uppercase; 72 | color: #fff; 73 | } 74 | 75 | .bp-header__desc { 76 | font-size: 0.95em; 77 | margin: 0.5em 0 1em; 78 | padding: 0; 79 | } 80 | 81 | .bp-header__present { 82 | font-size: 0.85em; 83 | font-weight: 700; 84 | position: relative; 85 | z-index: 100; 86 | display: block; 87 | padding: 0 0 0.6em 0.1em; 88 | letter-spacing: 0.5em; 89 | text-transform: uppercase; 90 | color: #5c5edc; 91 | } 92 | 93 | .bp-tooltip:after { 94 | font-size: 50%; 95 | font-size: 75%; 96 | position: relative; 97 | top: -8px; 98 | left: -12px; 99 | width: 30px; 100 | height: 30px; 101 | } 102 | 103 | .bp-tooltip:hover:before { 104 | content: attr(data-content); 105 | font-size: 110%; 106 | font-weight: 700; 107 | line-height: 1.2; 108 | position: absolute; 109 | left: auto; 110 | margin-left: 4px; 111 | padding: 0.8em 1em; 112 | text-align: left; 113 | text-indent: 0; 114 | letter-spacing: 0; 115 | text-transform: none; 116 | color: #fff; 117 | background: #5c5edc; 118 | } 119 | 120 | .bp-nav { 121 | margin: 0 0 0 -0.75em; 122 | } 123 | 124 | .bp-nav__item { 125 | position: relative; 126 | display: inline-block; 127 | width: 2.5em; 128 | height: 2.5em; 129 | margin: 0 0.1em; 130 | text-align: left; 131 | border-radius: 50%; 132 | } 133 | 134 | .bp-nav__item > span { 135 | display: none; 136 | } 137 | 138 | .bp-nav__item:hover:before { 139 | content: attr(data-info); 140 | font-size: 0.85em; 141 | font-weight: bold; 142 | position: absolute; 143 | top: 120%; 144 | left: 0; 145 | width: 600%; 146 | text-align: left; 147 | pointer-events: none; 148 | color: #595a5f; 149 | } 150 | 151 | .bp-nav__item:hover { 152 | background: #5c5edc; 153 | } 154 | 155 | .bp-icon:after { 156 | font-family: 'bpicons'; 157 | font-weight: normal; 158 | font-style: normal; 159 | font-variant: normal; 160 | text-align: center; 161 | text-transform: none; 162 | color: #5c5edc; 163 | -webkit-font-smoothing: antialiased; 164 | 165 | speak: none; 166 | } 167 | 168 | .bp-nav .bp-icon:after { 169 | line-height: 2.4; 170 | position: absolute; 171 | top: 0; 172 | left: 0; 173 | width: 100%; 174 | height: 100%; 175 | text-indent: 0; 176 | } 177 | 178 | .bp-nav a:hover:after { 179 | color: #fff; 180 | } 181 | 182 | .bp-icon--next:after { 183 | content: '\e000'; 184 | } 185 | 186 | .bp-icon--drop:after { 187 | content: '\e001'; 188 | } 189 | 190 | .bp-icon--archive:after { 191 | content: '\e002'; 192 | } 193 | 194 | .bp-icon--about:after { 195 | content: '\e003'; 196 | } 197 | 198 | .bp-icon--prev:after { 199 | content: '\e004'; 200 | } 201 | 202 | @media screen and (max-width: 40em) { 203 | .bp-header { 204 | padding: 50px 20px 1em; 205 | } 206 | .bp-header__title { 207 | font-size: 1.8em; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/favicon.ico -------------------------------------------------------------------------------- /fonts/bpicons/bpicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/fonts/bpicons/bpicons.eot -------------------------------------------------------------------------------- /fonts/bpicons/bpicons.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 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /fonts/bpicons/bpicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/fonts/bpicons/bpicons.ttf -------------------------------------------------------------------------------- /fonts/bpicons/bpicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/fonts/bpicons/bpicons.woff -------------------------------------------------------------------------------- /fonts/bpicons/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/ -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/1.jpg -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/3.jpg -------------------------------------------------------------------------------- /images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/4.jpg -------------------------------------------------------------------------------- /images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/5.jpg -------------------------------------------------------------------------------- /images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codrops/PageStackNavigation/f6f0f1f156e067e9838a64e61ee17f588480c0c9/images/6.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Blueprint: Page Stack Navigation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 38 | 39 | 40 |
41 | 42 |
43 | 44 |
45 | Blueprint 46 |

Page Stack Navigation

47 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

48 | 54 |
55 | img01 56 |
57 | 58 |
59 |
60 |

Documentation

61 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

62 |

63 | "We cannot have peace among men whose hearts find delight in killing any living creature." — Rachel Carson 64 |

65 |
66 | img06 67 |
68 |
69 |
70 |

Manuals

71 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

72 |

73 | "When you adopt a vegan diet we make a connection, you don't go back, it is not a diet, it is a lifestyle." — Freelee Frugivore 74 |

75 |
76 | img02 77 |
78 |
79 |
80 |

Software & Downloads

81 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

82 |

83 | "I decided to pick the diet that I thought would maximize my chances of long-term survival." — Al Gore 84 |

85 |
86 | img03 87 |
88 |
89 |
90 |

Customization & Settings

91 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

92 |

93 | "You have to make a conscious decision to change for your own well-being, that of your family and your country." —Bill Clinton 94 |

95 |
96 | img04 97 |
98 |
99 |
100 |

Training & Learning Center

101 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

102 |

103 | "The moment I began to understand what was going on with the treatment of animals, it led me more and more in the way of the path I am [on] now, which is a complete vegan." — Bryan Adams 104 |

105 |
106 | img05 107 |
108 |
109 |
110 |

Where to buy

111 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

112 |

113 | "When people ask me why I don't eat meat or any other animal products, I say, 'Because they are unhealthy and they are the product of a violent and inhumane industry.'" — 114 |

115 |
116 | img06 117 |
118 |
119 |
120 |

Blog & News

121 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

122 |

123 | "The question is not, 'Can they reason?' nor, 'Can they talk?' but rather, 'Can they suffer?" — Jeremy Bentham 124 |

125 |
126 | img01 127 |
128 |
129 |
130 |

Contact

131 |

Based on Ilya Kostin's Dribbble shot Stacked navigation

132 |

133 | "Man is the only animal that can remain on friendly terms with the victims he intends to eat until he eats them." — Samuel Butler 134 |

135 |
136 | img04 137 |
138 |
139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /js/classie.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * classie v1.0.1 3 | * class helper functions 4 | * from bonzo https://github.com/ded/bonzo 5 | * MIT license 6 | * 7 | * classie.has( elem, 'my-class' ) -> true/false 8 | * classie.add( elem, 'my-new-class' ) 9 | * classie.remove( elem, 'my-unwanted-class' ) 10 | * classie.toggle( elem, 'my-class' ) 11 | */ 12 | 13 | /*jshint browser: true, strict: true, undef: true, unused: true */ 14 | /*global define: false, module: false */ 15 | 16 | ( function( window ) { 17 | 18 | 'use strict'; 19 | 20 | // class helper functions from bonzo https://github.com/ded/bonzo 21 | 22 | function classReg( className ) { 23 | return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); 24 | } 25 | 26 | // classList support for class management 27 | // altho to be fair, the api sucks because it won't accept multiple classes at once 28 | var hasClass, addClass, removeClass; 29 | 30 | if ( 'classList' in document.documentElement ) { 31 | hasClass = function( elem, c ) { 32 | return elem.classList.contains( c ); 33 | }; 34 | addClass = function( elem, c ) { 35 | elem.classList.add( c ); 36 | }; 37 | removeClass = function( elem, c ) { 38 | elem.classList.remove( c ); 39 | }; 40 | } 41 | else { 42 | hasClass = function( elem, c ) { 43 | return classReg( c ).test( elem.className ); 44 | }; 45 | addClass = function( elem, c ) { 46 | if ( !hasClass( elem, c ) ) { 47 | elem.className = elem.className + ' ' + c; 48 | } 49 | }; 50 | removeClass = function( elem, c ) { 51 | elem.className = elem.className.replace( classReg( c ), ' ' ); 52 | }; 53 | } 54 | 55 | function toggleClass( elem, c ) { 56 | var fn = hasClass( elem, c ) ? removeClass : addClass; 57 | fn( elem, c ); 58 | } 59 | 60 | var classie = { 61 | // full names 62 | hasClass: hasClass, 63 | addClass: addClass, 64 | removeClass: removeClass, 65 | toggleClass: toggleClass, 66 | // short names 67 | has: hasClass, 68 | add: addClass, 69 | remove: removeClass, 70 | toggle: toggleClass 71 | }; 72 | 73 | // transport 74 | if ( typeof define === 'function' && define.amd ) { 75 | // AMD 76 | define( classie ); 77 | } else if ( typeof exports === 'object' ) { 78 | // CommonJS 79 | module.exports = classie; 80 | } else { 81 | // browser global 82 | window.classie = classie; 83 | } 84 | 85 | })( window ); -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * main.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2015, Codrops 9 | * http://www.codrops.com 10 | */ 11 | ;(function(window) { 12 | 13 | 'use strict'; 14 | 15 | var support = { transitions: Modernizr.csstransitions }, 16 | // transition end event name 17 | transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, 18 | transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], 19 | onEndTransition = function( el, callback ) { 20 | var onEndCallbackFn = function( ev ) { 21 | if( support.transitions ) { 22 | if( ev.target != this ) return; 23 | this.removeEventListener( transEndEventName, onEndCallbackFn ); 24 | } 25 | if( callback && typeof callback === 'function' ) { callback.call(this); } 26 | }; 27 | if( support.transitions ) { 28 | el.addEventListener( transEndEventName, onEndCallbackFn ); 29 | } 30 | else { 31 | onEndCallbackFn(); 32 | } 33 | }, 34 | // the pages wrapper 35 | stack = document.querySelector('.pages-stack'), 36 | // the page elements 37 | pages = [].slice.call(stack.children), 38 | // total number of page elements 39 | pagesTotal = pages.length, 40 | // index of current page 41 | current = 0, 42 | // menu button 43 | menuCtrl = document.querySelector('button.menu-button'), 44 | // the navigation wrapper 45 | nav = document.querySelector('.pages-nav'), 46 | // the menu nav items 47 | navItems = [].slice.call(nav.querySelectorAll('.link--page')), 48 | // check if menu is open 49 | isMenuOpen = false; 50 | 51 | function init() { 52 | buildStack(); 53 | initEvents(); 54 | } 55 | 56 | function buildStack() { 57 | var stackPagesIdxs = getStackPagesIdxs(); 58 | 59 | // set z-index, opacity, initial transforms to pages and add class page--inactive to all except the current one 60 | for(var i = 0; i < pagesTotal; ++i) { 61 | var page = pages[i], 62 | posIdx = stackPagesIdxs.indexOf(i); 63 | 64 | if( current !== i ) { 65 | classie.add(page, 'page--inactive'); 66 | 67 | if( posIdx !== -1 ) { 68 | // visible pages in the stack 69 | page.style.WebkitTransform = 'translate3d(0,100%,0)'; 70 | page.style.transform = 'translate3d(0,100%,0)'; 71 | } 72 | else { 73 | // invisible pages in the stack 74 | page.style.WebkitTransform = 'translate3d(0,75%,-300px)'; 75 | page.style.transform = 'translate3d(0,75%,-300px)'; 76 | } 77 | } 78 | else { 79 | classie.remove(page, 'page--inactive'); 80 | } 81 | 82 | page.style.zIndex = i < current ? parseInt(current - i) : parseInt(pagesTotal + current - i); 83 | 84 | if( posIdx !== -1 ) { 85 | page.style.opacity = parseFloat(1 - 0.1 * posIdx); 86 | } 87 | else { 88 | page.style.opacity = 0; 89 | } 90 | } 91 | } 92 | 93 | // event binding 94 | function initEvents() { 95 | // menu button click 96 | menuCtrl.addEventListener('click', toggleMenu); 97 | 98 | // navigation menu clicks 99 | navItems.forEach(function(item) { 100 | // which page to open? 101 | var pageid = item.getAttribute('href').slice(1); 102 | item.addEventListener('click', function(ev) { 103 | ev.preventDefault(); 104 | openPage(pageid); 105 | }); 106 | }); 107 | 108 | // clicking on a page when the menu is open triggers the menu to close again and open the clicked page 109 | pages.forEach(function(page) { 110 | var pageid = page.getAttribute('id'); 111 | page.addEventListener('click', function(ev) { 112 | if( isMenuOpen ) { 113 | ev.preventDefault(); 114 | openPage(pageid); 115 | } 116 | }); 117 | }); 118 | 119 | // keyboard navigation events 120 | document.addEventListener( 'keydown', function( ev ) { 121 | if( !isMenuOpen ) return; 122 | var keyCode = ev.keyCode || ev.which; 123 | if( keyCode === 27 ) { 124 | closeMenu(); 125 | } 126 | } ); 127 | } 128 | 129 | // toggle menu fn 130 | function toggleMenu() { 131 | if( isMenuOpen ) { 132 | closeMenu(); 133 | } 134 | else { 135 | openMenu(); 136 | isMenuOpen = true; 137 | } 138 | } 139 | 140 | // opens the menu 141 | function openMenu() { 142 | // toggle the menu button 143 | classie.add(menuCtrl, 'menu-button--open') 144 | // stack gets the class "pages-stack--open" to add the transitions 145 | classie.add(stack, 'pages-stack--open'); 146 | // reveal the menu 147 | classie.add(nav, 'pages-nav--open'); 148 | 149 | // now set the page transforms 150 | var stackPagesIdxs = getStackPagesIdxs(); 151 | for(var i = 0, len = stackPagesIdxs.length; i < len; ++i) { 152 | var page = pages[stackPagesIdxs[i]]; 153 | page.style.WebkitTransform = 'translate3d(0, 75%, ' + parseInt(-1 * 200 - 50*i) + 'px)'; // -200px, -230px, -260px 154 | page.style.transform = 'translate3d(0, 75%, ' + parseInt(-1 * 200 - 50*i) + 'px)'; 155 | } 156 | } 157 | 158 | // closes the menu 159 | function closeMenu() { 160 | // same as opening the current page again 161 | openPage(); 162 | } 163 | 164 | // opens a page 165 | function openPage(id) { 166 | var futurePage = id ? document.getElementById(id) : pages[current], 167 | futureCurrent = pages.indexOf(futurePage), 168 | stackPagesIdxs = getStackPagesIdxs(futureCurrent); 169 | 170 | // set transforms for the new current page 171 | futurePage.style.WebkitTransform = 'translate3d(0, 0, 0)'; 172 | futurePage.style.transform = 'translate3d(0, 0, 0)'; 173 | futurePage.style.opacity = 1; 174 | 175 | // set transforms for the other items in the stack 176 | for(var i = 0, len = stackPagesIdxs.length; i < len; ++i) { 177 | var page = pages[stackPagesIdxs[i]]; 178 | page.style.WebkitTransform = 'translate3d(0,100%,0)'; 179 | page.style.transform = 'translate3d(0,100%,0)'; 180 | } 181 | 182 | // set current 183 | if( id ) { 184 | current = futureCurrent; 185 | } 186 | 187 | // close menu.. 188 | classie.remove(menuCtrl, 'menu-button--open'); 189 | classie.remove(nav, 'pages-nav--open'); 190 | onEndTransition(futurePage, function() { 191 | classie.remove(stack, 'pages-stack--open'); 192 | // reorganize stack 193 | buildStack(); 194 | isMenuOpen = false; 195 | }); 196 | } 197 | 198 | // gets the current stack pages indexes. If any of them is the excludePage then this one is not part of the returned array 199 | function getStackPagesIdxs(excludePageIdx) { 200 | var nextStackPageIdx = current + 1 < pagesTotal ? current + 1 : 0, 201 | nextStackPageIdx_2 = current + 2 < pagesTotal ? current + 2 : 1, 202 | idxs = [], 203 | 204 | excludeIdx = excludePageIdx || -1; 205 | 206 | if( excludePageIdx != current ) { 207 | idxs.push(current); 208 | } 209 | if( excludePageIdx != nextStackPageIdx ) { 210 | idxs.push(nextStackPageIdx); 211 | } 212 | if( excludePageIdx != nextStackPageIdx_2 ) { 213 | idxs.push(nextStackPageIdx_2); 214 | } 215 | 216 | return idxs; 217 | } 218 | 219 | init(); 220 | 221 | //changes to a page such as id="page-manuals" without opening the menu and preserving menu transition functionality 222 | window.openPageNoTransition = function(id){ 223 | 224 | var futurePage = id ? document.getElementById(id) : pages[current], 225 | futureCurrent = pages.indexOf(futurePage), 226 | stackPagesIdxs = getStackPagesIdxs(futureCurrent); 227 | 228 | // set transforms for the new current page 229 | futurePage.style.WebkitTransform = 'translate3d(0, 0, 0)'; 230 | futurePage.style.transform = 'translate3d(0, 0, 0)'; 231 | futurePage.style.opacity = 1; 232 | 233 | classie.remove(futurePage, 'page--inactive'); 234 | 235 | // set current 236 | if( id ) { 237 | current = futureCurrent; 238 | } 239 | 240 | buildStack(); 241 | } 242 | })(window); -------------------------------------------------------------------------------- /js/modernizr-custom.js: -------------------------------------------------------------------------------- 1 | /*! modernizr 3.1.0 (Custom Build) | MIT * 2 | * http://modernizr.com/download/?-csstransitions-prefixed !*/ 3 | !function(e,n,t){function r(e){var n=C.className,t=Modernizr._config.classPrefix||"";if(_&&(n=n.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+t+"no-js(\\s|$)");n=n.replace(r,"$1"+t+"js$2")}Modernizr._config.enableClasses&&(n+=" "+t+e.join(" "+t),_?C.className.baseVal=n:C.className=n)}function o(e,n){return typeof e===n}function s(){var e,n,t,r,s,i,a;for(var f in w)if(w.hasOwnProperty(f)){if(e=[],n=w[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;td;d++)if(v=e[d],h=N.style[v],a(v,"-")&&(v=i(v)),N.style[v]!==t){if(s||o(r,"undefined"))return l(),"pfx"==n?v:!0;try{N.style[v]=r}catch(g){}if(N.style[v]!=h)return l(),"pfx"==n?v:!0}return l(),!1}function h(e,n,t,r,s){var i=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+b.join(i+" ")+i).split(" ");return o(n,"string")||o(n,"undefined")?v(a,n,r,s):(a=(e+" "+P.join(i+" ")+i).split(" "),u(a,n,t))}function y(e,n,r){return h(e,t,t,n,r)}var g=[],C=n.documentElement,_="svg"===C.nodeName.toLowerCase(),w=[],x={_version:"3.1.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){w.push({name:e,fn:n,options:t})},addAsyncTest:function(e){w.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=x,Modernizr=new Modernizr;var S="Moz O ms Webkit",b=x._config.usePrefixes?S.split(" "):[];x._cssomPrefixes=b;var E=function(n){var r,o=prefixes.length,s=e.CSSRule;if("undefined"==typeof s)return t;if(!n)return!1;if(n=n.replace(/^@/,""),r=n.replace(/-/g,"_").toUpperCase()+"_RULE",r in s)return"@"+n;for(var i=0;o>i;i++){var a=prefixes[i],f=a.toUpperCase()+"_"+r;if(f in s)return"@-"+a.toLowerCase()+"-"+n}return!1};x.atRule=E;var P=x._config.usePrefixes?S.toLowerCase().split(" "):[];x._domPrefixes=P;var z={elem:f("modernizr")};Modernizr._q.push(function(){delete z.elem});var N={style:z.elem.style};Modernizr._q.unshift(function(){delete N.style}),x.testAllProps=h;x.prefixed=function(e,n,t){return 0===e.indexOf("@")?E(e):(-1!=e.indexOf("-")&&(e=i(e)),n?h(e,n,t):h(e,"pfx"))};x.testAllProps=y,Modernizr.addTest("csstransitions",y("transition","all",!0)),s(),r(g),delete x.addTest,delete x.addAsyncTest;for(var T=0;T