├── README.md ├── index.html ├── js ├── makisu.min.js └── makisu.js └── css └── style.css /README.md: -------------------------------------------------------------------------------- 1 | ### Makisu 2 | 3 | An experimental CSS 3D dropdown concept, wrapped up in a [jQuery](http://jquery.com/) plugin. 4 | 5 | Check out the [demo](http://soulwire.github.com/Makisu/) _(you'll need a CSS 3D capable browser, such as [Chrome](www.google.com/chrome).)_ 6 | 7 | A current list of supported browsers can be found [here](http://caniuse.com/#search=3d%20transform). 8 | 9 | #### Example usage 10 | 11 | Use it like any regular jQuery plugin: 12 | 13 | $( '.list' ).makisu({ 14 | selector: 'li', 15 | overlap: 0.2, 16 | speed: 0.8 17 | }); 18 | 19 | The options available are: 20 | 21 | - `selector` Children matching this selector will be _folded_ into the Makisu 22 | - `speed` The animation duration (in _seconds_) for each folding item 23 | - `overlap` Fraction of `speed ` by which folding items overlap (`0` to `1`) 24 | - `shading` Default shading colour (`null` for no shading) 25 | - `perspective` Perspective to apply to 3D transformed objects 26 | 27 | #### API 28 | 29 | Once an element has been extended as in the example above, you can `open`, `close` and `toggle` it. 30 | 31 | $( '.list' ).makisu( 'open' ); 32 | 33 | #### Trivia 34 | 35 | The name comes from the [object](http://en.wikipedia.org/wiki/Makisu) that inspired it. 36 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Makisu ~ CSS 3D Dropdown Concept 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |

Makisu

13 |

CSS 3D Dropdown Concept

14 |
15 |
16 | 17 |
18 | 19 |
20 |
Nigiri
21 |
Maguro
22 |
Sake
23 |
Unagi
24 |
Buri
25 |
Suzuki
26 |
Saba
27 |
Iwashi
28 |
Kohada
29 |
Hirame
30 |
Tobiwo
31 |
32 | 33 |
34 |
Maki
35 |
Ana-kyu
36 |
Chutoro
37 |
Kaiware
38 |
Kampyo
39 |
Kappa
40 |
Natto
41 |
Negitoro
42 |
Oshinko
43 |
Otoro
44 |
Tekka
45 |
46 | 47 |
48 |
Sashimi
49 |
Maguro
50 |
Toro
51 |
Ebi
52 |
Saba
53 |
Ika
54 |
Tako
55 |
Tomago
56 |
Kani
57 |
Katsuo
58 |
Maguro
59 |
60 | 61 | Toggle 62 | 63 |
64 | 65 |
66 |
67 |

CSS 3D Not Detected :(

68 |

I couldn't detect your browser's CSS 3D capabilities. If I'm wrong, please file an issue, otherwise, try a sexier browser

69 |
70 |
71 | 72 | Fork me on GitHub 73 | 74 | 75 | 76 | 128 | 129 | -------------------------------------------------------------------------------- /js/makisu.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2012 by Justin Windle 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */(function(e){var t=!1,n=document.createElement("div"),r=/^(Moz|(w|W)ebkit|O|ms)(?=[A-Z])/,i=function(){for(var e in n.style)if(r.test(e))return e.match(r)[0]}()||"",s=i+"Perspective"in n.style,o="-"+i.toLowerCase()+"-",u,a,f,l,c,h,p,d,v,m,g,y={toggle:function(){u=e(this),u.makisu(u.hasClass("open")?"close":"open")},open:function(t,n,r){u=e(this),a=u.find(".root"),l=u.find(".node").not(a),t=b.resolve(u,"speed",t),r=b.resolve(u,"easing",r),n=b.resolve(u,"overlap",n),l.each(function(i,s){m="unfold"+(i?"":"-first"),g=i===l.length-1,time=t*(1-n),v=i*time,h=e(s),p=h.find(".over"),h.css(b.prefix({transform:"rotateX(180deg)",animation:m+" "+t+"s "+r+" "+v+"s 1 normal forwards"})),g||(v=(i+1)*time),p.css(b.prefix({animation:"unfold-over "+t*.45+"s "+r+" "+v+"s 1 normal forwards"}))}),a.css(b.prefix({animation:"swing-out "+l.length*time*1.4+"s ease-in-out 0s 1 normal forwards"})),u.addClass("open")},close:function(t,n,r){u=e(this),a=u.find(".root"),l=u.find(".node").not(a),t=b.resolve(u,"speed",t)*.66,r=b.resolve(u,"easing",r),n=b.resolve(u,"overlap",n),l.each(function(i,s){m="fold"+(i?"":"-first"),g=i===0,time=t*(1-n),v=(l.length-i-1)*time,h=e(s),p=h.find(".over"),h.css(b.prefix({transform:"rotateX(0deg)",animation:m+" "+t+"s "+r+" "+v+"s 1 normal forwards"})),g||(v=(l.length-i-2)*time+t*.35),p.css(b.prefix({animation:"fold-over "+t*.45+"s "+r+" "+v+"s 1 normal forwards"}))}),a.css(b.prefix({animation:"swing-in "+l.length*time*1+"s ease-in-out 0s 1 normal forwards"})),u.removeClass("open")}},b={resolve:function(e,t,n){return typeof n=="undefined"?e.data(t):n},prefix:function(e){for(var t in e)e[o+t]=e[t];return e},inject:function(e){try{var t=document.createElement("style");t.innerHTML=e,document.getElementsByTagName("head")[0].appendChild(t)}catch(n){}}},w={node:'',back:'',over:''};e.fn.makisu=function(n){if(!s){var r="Failed to detect CSS 3D support";console&&console.warn&&(console.warn(r),this.each(function(){e(this).trigger("error",r)}));return}t||(t=!0,b.inject("@"+o+"keyframes unfold {"+"0% {"+o+"transform: rotateX(180deg); }"+"50% {"+o+"transform: rotateX(-30deg); }"+"100% {"+o+"transform: rotateX(0deg); }"+"}"),b.inject("@"+o+"keyframes unfold-first {"+"0% {"+o+"transform: rotateX(-90deg); }"+"50% {"+o+"transform: rotateX(60deg); }"+"100% {"+o+"transform: rotateX(0deg); }"+"}"),b.inject("@"+o+"keyframes fold {"+"0% {"+o+"transform: rotateX(0deg); }"+"100% {"+o+"transform: rotateX(180deg); }"+"}"),b.inject("@"+o+"keyframes fold-first {"+"0% {"+o+"transform: rotateX(0deg); }"+"100% {"+o+"transform: rotateX(-180deg); }"+"}"),b.inject("@"+o+"keyframes swing-out {"+"0% {"+o+"transform: rotateX(0deg); }"+"30% {"+o+"transform: rotateX(-30deg); }"+"60% {"+o+"transform: rotateX(15deg); }"+"100% {"+o+"transform: rotateX(0deg); }"+"}"),b.inject("@"+o+"keyframes swing-in {"+"0% {"+o+"transform: rotateX(0deg); }"+"50% {"+o+"transform: rotateX(-10deg); }"+"90% {"+o+"transform: rotateX(15deg); }"+"100% {"+o+"transform: rotateX(0deg); }"+"}"),b.inject("@"+o+"keyframes unfold-over {"+"0% { opacity: 1.0; }"+"100% { opacity: 0.0; }"+"}"),b.inject("@"+o+"keyframes fold-over {"+"0% { opacity: 0.0; }"+"100% { opacity: 1.0; }"+"}"),b.inject(".node {position: relative;display: block;}"),b.inject(".face {pointer-events: none;position: absolute;display: block;height: 100%;width: 100%;left: 0;top: 0;}"));var i=e.extend({},e.fn.makisu.defaults,n),v=Array.prototype.slice.call(arguments,1);return this.each(function(){if(y[n])return y[n].apply(this,v);u=e(this).data(i),u.data("initialized")||(u.data("initialized",!0),l=u.children(i.selector),a=e(w.node).addClass("root"),f=a,l.each(function(t,n){h=e(n),m="fold"+(t?"":"-first"),h.css("position","relative"),h.css(b.prefix({"transform-style":"preserve-3d",transform:"translateZ(-0.1px)"})),d=e(w.back),d.css("background",h.css("background")),d.css(b.prefix({transform:"translateZ(-0.1px)"})),p=e(w.over),p.css(b.prefix({transform:"translateZ(0.1px)"})),p.css({background:i.shading,opacity:0}),c=e(w.node).append(h),c.css(b.prefix({"transform-origin":"50% 0%","transform-style":"preserve-3d",animation:m+" 1ms linear 0s 1 normal forwards"})),h.append(p),h.append(d),f.append(c),f=c}),a.css(b.prefix({"transform-origin":"50% 0%","transform-style":"preserve-3d"})),u.css(b.prefix({transform:"perspective("+i.perspective+"px)"})),u.append(a))})},e.fn.makisu.defaults={perspective:1200,shading:"rgba(0,0,0,0.12)",selector:null,overlap:.6,speed:.8,easing:"ease-in-out"},e.fn.makisu.enabled=s})(jQuery); -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | 2 | html, body { 3 | 4 | -webkit-font-smoothing: antialiased; 5 | -moz-font-smoothing: antialiased; 6 | 7 | background: #ffffff; 8 | background: -moz-radial-gradient(center, ellipse cover, #ffffff 0%, #ffffff 26%, #f5f5f5 59%, #f5f5f5 77%, #cecece 100%); 9 | background: -webkit-gradient(radial, center center, 0, center center, 100%, color-stop(0%,#ffffff), color-stop(26%,#ffffff), color-stop(59%,#f5f5f5), color-stop(77%,#f5f5f5), color-stop(100%,#cecece)); 10 | background: -webkit-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); 11 | background: -o-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); 12 | background: -ms-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); 13 | background: radial-gradient(ellipse at center, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); 14 | font-family: 'Days One', sans-serif; 15 | overflow: hidden; 16 | padding: 0; 17 | margin: 0; 18 | height: 100%; 19 | } 20 | 21 | body:before { 22 | 23 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDRCNjE4NDcxMDgzMTFFMkFGQkM4MzE4NzI4RjhBMkQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDRCNjE4NDgxMDgzMTFFMkFGQkM4MzE4NzI4RjhBMkQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpENEI2MTg0NTEwODMxMUUyQUZCQzgzMTg3MjhGOEEyRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpENEI2MTg0NjEwODMxMUUyQUZCQzgzMTg3MjhGOEEyRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp/mixwAABMrSURBVHjaNNrnrptV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); 24 | position: absolute; 25 | content: ''; 26 | opacity: 0.8; 27 | height: 100%; 28 | width: 100%; 29 | left: 0; 30 | top: 0; 31 | } 32 | 33 | a { 34 | 35 | -webkit-transition: all 250ms cubic-bezier(0.230, 1.000, 0.320, 1.000); 36 | -moz-transition: all 250ms cubic-bezier(0.230, 1.000, 0.320, 1.000); 37 | -ms-transition: all 250ms cubic-bezier(0.230, 1.000, 0.320, 1.000); 38 | -o-transition: all 250ms cubic-bezier(0.230, 1.000, 0.320, 1.000); 39 | transition: all 250ms cubic-bezier(0.230, 1.000, 0.320, 1.000); 40 | 41 | text-decoration: none; 42 | } 43 | 44 | .header { 45 | 46 | text-align: center; 47 | position: absolute; 48 | color: #333; 49 | width: 100%; 50 | top: 9%; 51 | } 52 | 53 | .header h1 { 54 | 55 | letter-spacing: -1px; 56 | text-shadow: -2px -1px 1px #fff, 1px 2px 2px rgba(0, 0, 0, 0.2); 57 | font-weight: 300; 58 | font-size: 36px; 59 | margin: 0; 60 | } 61 | 62 | .header h2 { 63 | 64 | text-transform: uppercase; 65 | text-shadow: -2px -1px 1px #fff, 1px 1px 1px rgba(0, 0, 0, 0.15); 66 | font-weight: 300; 67 | font-size: 12px; 68 | color: rgba(0,0,0,0.7); 69 | margin: 0; 70 | } 71 | 72 | .demo:after { 73 | 74 | box-shadow: 0 1px 16px rgba(0,0,0,0.15); 75 | background: #1b1b1b; 76 | position: absolute; 77 | content: ''; 78 | height: 10px; 79 | width: 100%; 80 | top: 0; 81 | } 82 | 83 | /* List styles */ 84 | 85 | .list { 86 | 87 | -webkit-transform-style: preserve-3d; 88 | -moz-transform-style: preserve-3d; 89 | -ms-transform-style: preserve-3d; 90 | -o-transform-style: preserve-3d; 91 | transform-style: preserve-3d; 92 | 93 | text-transform: uppercase; 94 | position: absolute; 95 | margin-left: -140px; 96 | margin-top: -280px; 97 | top: 55%; 98 | } 99 | 100 | .list a { 101 | 102 | display: block; 103 | color: #fff; 104 | } 105 | 106 | .list a:hover { 107 | text-indent: 20px; 108 | } 109 | 110 | .list dt, .list dd { 111 | 112 | text-indent: 10px; 113 | line-height: 55px; 114 | background: #E0FBAC; 115 | margin: 0; 116 | height: 55px; 117 | width: 270px; 118 | color: #fff; 119 | } 120 | 121 | .list dt { 122 | 123 | /* Since we're hiding elements behind here, we need it in 3d */ 124 | -webkit-transform: translateZ(0.3px); 125 | -moz-transform: translateZ(0.3px); 126 | -ms-transform: translateZ(0.3px); 127 | -o-transform: translateZ(0.3px); 128 | transform: translateZ(0.3px); 129 | 130 | text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); 131 | font-size: 15px; 132 | } 133 | 134 | .list dd { 135 | 136 | border-top: 1px dashed rgba(255,255,255,0.3); 137 | line-height: 35px; 138 | font-size: 11px; 139 | height: 35px; 140 | margin: 0; 141 | } 142 | 143 | /* UI */ 144 | 145 | .toggle { 146 | 147 | box-shadow: 0 1px 4px rgba(0,0,0,0.15); 148 | border-radius: 3px; 149 | 150 | text-transform: uppercase; 151 | letter-spacing: -1px; 152 | line-height: 50px; 153 | margin-left: -70px; 154 | margin-top: -20px; 155 | background: #2b2b2b; 156 | text-align: center; 157 | font-size: 12px; 158 | position: absolute; 159 | height: 50px; 160 | bottom: 10%; 161 | width: 140px; 162 | color: #fff; 163 | left: 50%; 164 | } 165 | 166 | .toggle:hover { 167 | 168 | background: #E42692; 169 | } 170 | 171 | /* No CSS 3D support warning */ 172 | .warning { 173 | 174 | -webkit-transform: translateZ(2px); 175 | -moz-transform: translateZ(2px); 176 | -ms-transform: translateZ(2px); 177 | -o-transform: translateZ(2px); 178 | transform: translateZ(2px); 179 | 180 | background: rgba(255,255,255,0.6); 181 | position: fixed; 182 | display: none; 183 | z-index: 999; 184 | height: 100%; 185 | width: 100%; 186 | left: 0; 187 | top: 0; 188 | } 189 | 190 | .warning .message { 191 | 192 | box-shadow: 0 1px 8px rgba(0, 0, 0, 0.6); 193 | border-radius: 5px; 194 | text-align: center; 195 | margin-left: -150px; 196 | margin-top: -60px; 197 | line-height: 1.5; 198 | background: #222; 199 | font-size: 12px; 200 | position: absolute; 201 | padding: 10px; 202 | width: 280px; 203 | color: #fff; 204 | left: 50%; 205 | top: 50%; 206 | } 207 | 208 | .warning .message h1 { 209 | 210 | font-weight: 300; 211 | font-size: 14px; 212 | } 213 | 214 | .warning .message a { 215 | 216 | text-decoration: none; 217 | color: #73C8A9; 218 | } 219 | 220 | /* Individual styles */ 221 | 222 | .sashimi dt, .sashimi dd, .sashimi a { background: #73C8A9; } 223 | .nigiri dt, .nigiri dd, .nigiri a { background: #E32551; } 224 | .maki dt, .maki dd, .maki a { background: #FFC219; } 225 | 226 | .sashimi a:hover { background: #61c19e; } 227 | .nigiri a:hover { background: #d31b46; } 228 | .maki a:hover { background: #ffbb00; } 229 | 230 | .nigiri { 231 | 232 | -webkit-transform: perspective(1200px) rotateY(40deg) !important; 233 | -moz-transform: perspective(1200px) rotateY(40deg) !important; 234 | -ms-transform: perspective(1200px) rotateY(40deg) !important; 235 | -o-transform: perspective(1200px) rotateY(40deg) !important; 236 | transform: perspective(1200px) rotateY(40deg) !important; 237 | 238 | -webkit-transform-origin: 110% 25%; 239 | -moz-transform-origin: 110% 25%; 240 | -ms-transform-origin: 110% 25%; 241 | -o-transform-origin: 110% 25%; 242 | transform-origin: 110% 25%; 243 | 244 | left: 20%; 245 | } 246 | 247 | .maki { 248 | 249 | -webkit-transform: perspective(600px) translateZ(1px) !important; 250 | -moz-transform: perspective(600px) translateZ(1px) !important; 251 | -ms-transform: perspective(600px) translateZ(1px) !important; 252 | -o-transform: perspective(600px) translateZ(1px) !important; 253 | transform: perspective(600px) translateZ(1px) !important; 254 | 255 | left: 50%; 256 | } 257 | 258 | .sashimi { 259 | 260 | -webkit-transform: perspective(1200px) rotateY(-40deg) !important; 261 | -moz-transform: perspective(1200px) rotateY(-40deg) !important; 262 | -ms-transform: perspective(1200px) rotateY(-40deg) !important; 263 | -o-transform: perspective(1200px) rotateY(-40deg) !important; 264 | transform: perspective(1200px) rotateY(-40deg) !important; 265 | 266 | -webkit-transform-origin: -10% 25%; 267 | -moz-transform-origin: -10% 25%; 268 | -ms-transform-origin: -10% 25%; 269 | -o-transform-origin: -10% 25%; 270 | transform-origin: -10% 25%; 271 | 272 | left: 80%; 273 | } -------------------------------------------------------------------------------- /js/makisu.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Copyright (C) 2012 by Justin Windle 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | */ 23 | 24 | (function($) { 25 | 26 | // Global initialisation flag 27 | var initialized = false; 28 | 29 | // For detecting browser prefix and capabilities 30 | var el = document.createElement( 'div' ); 31 | var re = /^(Moz|(w|W)ebkit|O|ms)(?=[A-Z])/; 32 | 33 | // Establish vendor prefix and CSS 3D support 34 | var vendor = (function() { for ( var p in el.style ) if( re.test(p) ) return p.match(re)[0]; })() || ''; 35 | var canRun = vendor + 'Perspective' in el.style; 36 | var prefix = '-' + vendor.toLowerCase() + '-'; 37 | 38 | var $this, $root, $base, $kids, $node, $item, $over, $back; 39 | var wait, anim, last; 40 | 41 | // Public API 42 | var api = { 43 | 44 | // Toggle open / closed 45 | toggle: function() { 46 | 47 | $this = $( this ); 48 | $this.makisu( $this.hasClass( 'open' ) ? 'close' : 'open' ); 49 | }, 50 | 51 | // Trigger the unfold animation 52 | open: function( speed, overlap, easing ) { 53 | 54 | // Cache DOM references 55 | $this = $(this); 56 | $root = $this.find( '.root' ); 57 | $kids = $this.find( '.node' ).not( $root ); 58 | 59 | // Establish values or fallbacks 60 | speed = utils.resolve( $this, 'speed', speed ); 61 | easing = utils.resolve( $this, 'easing', easing ); 62 | overlap = utils.resolve( $this, 'overlap', overlap ); 63 | 64 | $kids.each( function( index, el ) { 65 | 66 | // Establish settings for this iteration 67 | anim = 'unfold' + ( !index ? '-first' : '' ); 68 | last = index === $kids.length - 1; 69 | time = speed * ( 1 - overlap ); 70 | wait = index * time; 71 | 72 | // Cache DOM references 73 | $item = $( el ); 74 | $over = $item.find( '.over' ); 75 | 76 | // Element animation 77 | $item.css(utils.prefix({ 78 | 'transform': 'rotateX(180deg)', 79 | 'animation': anim + ' ' + speed + 's ' + easing + ' ' + wait + 's 1 normal forwards' 80 | })); 81 | 82 | // Shading animation happens when the next item starts 83 | if ( !last ) wait = ( index + 1 ) * time; 84 | 85 | // Shading animation 86 | $over.css(utils.prefix({ 87 | 'animation': 'unfold-over ' + (speed * 0.45) + 's ' + easing + ' ' + wait + 's 1 normal forwards' 88 | })); 89 | }); 90 | 91 | // Add momentum to the container 92 | $root.css(utils.prefix({ 93 | 'animation': 'swing-out ' + ( $kids.length * time * 1.4 ) + 's ease-in-out 0s 1 normal forwards' 94 | })); 95 | 96 | $this.addClass( 'open' ); 97 | }, 98 | 99 | // Trigger the fold animation 100 | close: function( speed, overlap, easing ) { 101 | 102 | // Cache DOM references 103 | $this = $(this); 104 | $root = $this.find( '.root' ); 105 | $kids = $this.find( '.node' ).not( $root ); 106 | 107 | // Establish values or fallbacks 108 | speed = utils.resolve( $this, 'speed', speed ) * 0.66; 109 | easing = utils.resolve( $this, 'easing', easing ); 110 | overlap = utils.resolve( $this, 'overlap', overlap ); 111 | 112 | $kids.each( function( index, el ) { 113 | 114 | // Establish settings for this iteration 115 | anim = 'fold' + ( !index ? '-first' : '' ); 116 | last = index === 0; 117 | time = speed * ( 1 - overlap ); 118 | wait = ( $kids.length - index - 1 ) * time; 119 | 120 | // Cache DOM references 121 | $item = $( el ); 122 | $over = $item.find( '.over' ); 123 | 124 | // Element animation 125 | $item.css(utils.prefix({ 126 | 'transform': 'rotateX(0deg)', 127 | 'animation': anim + ' ' + speed + 's ' + easing + ' ' + wait + 's 1 normal forwards' 128 | })); 129 | 130 | // Adjust delay for shading 131 | if ( !last ) wait = ( ( $kids.length - index - 2 ) * time ) + ( speed * 0.35 ); 132 | 133 | // Shading animation 134 | $over.css(utils.prefix({ 135 | 'animation': 'fold-over ' + (speed * 0.45) + 's ' + easing + ' ' + wait + 's 1 normal forwards' 136 | })); 137 | }); 138 | 139 | // Add momentum to the container 140 | $root.css(utils.prefix({ 141 | 'animation': 'swing-in ' + ( $kids.length * time * 1.0 ) + 's ease-in-out 0s 1 normal forwards' 142 | })); 143 | 144 | $this.removeClass( 'open' ); 145 | } 146 | }; 147 | 148 | // Utils 149 | var utils = { 150 | 151 | // Resolves argument values to defaults 152 | resolve: function( $el, key, val ) { 153 | return typeof val === 'undefined' ? $el.data( key ) : val; 154 | }, 155 | 156 | // Prefixes a hash of styles with the current vendor 157 | prefix: function( style ) { 158 | 159 | for ( var key in style ) { 160 | style[ prefix + key ] = style[ key ]; 161 | } 162 | 163 | return style; 164 | }, 165 | 166 | // Inserts rules into the document styles 167 | inject: function( rule ) { 168 | 169 | try { 170 | 171 | var style = document.createElement( 'style' ); 172 | style.innerHTML = rule; 173 | document.getElementsByTagName( 'head' )[0].appendChild( style ); 174 | 175 | } catch ( error ) {} 176 | } 177 | }; 178 | 179 | // Element templates 180 | var markup = { 181 | node: '', 182 | back: '', 183 | over: '' 184 | }; 185 | 186 | // Plugin definition 187 | $.fn.makisu = function( options ) { 188 | 189 | // Notify if 3D isn't available 190 | if ( !canRun ) { 191 | 192 | var message = 'Failed to detect CSS 3D support'; 193 | 194 | if( console && console.warn ) { 195 | 196 | // Print warning to the console 197 | console.warn( message ); 198 | 199 | // Trigger errors on elements 200 | this.each( function() { 201 | $( this ).trigger( 'error', message ); 202 | }); 203 | } 204 | 205 | return; 206 | } 207 | 208 | // Fires only once 209 | if ( !initialized ) { 210 | 211 | initialized = true; 212 | 213 | // Unfold 214 | utils.inject( '@' + prefix + 'keyframes unfold {' + 215 | 216 | '0% {' + prefix + 'transform: rotateX(180deg); }' + 217 | '50% {' + prefix + 'transform: rotateX(-30deg); }' + 218 | '100% {' + prefix + 'transform: rotateX(0deg); }' + 219 | 220 | '}'); 221 | 222 | // Unfold (first item) 223 | utils.inject( '@' + prefix + 'keyframes unfold-first {' + 224 | 225 | '0% {' + prefix + 'transform: rotateX(-90deg); }' + 226 | '50% {' + prefix + 'transform: rotateX(60deg); }' + 227 | '100% {' + prefix + 'transform: rotateX(0deg); }' + 228 | 229 | '}'); 230 | 231 | // Fold 232 | utils.inject( '@' + prefix + 'keyframes fold {' + 233 | 234 | '0% {' + prefix + 'transform: rotateX(0deg); }' + 235 | '100% {' + prefix + 'transform: rotateX(180deg); }' + 236 | 237 | '}'); 238 | 239 | // Fold (first item) 240 | utils.inject( '@' + prefix + 'keyframes fold-first {' + 241 | 242 | '0% {' + prefix + 'transform: rotateX(0deg); }' + 243 | '100% {' + prefix + 'transform: rotateX(-180deg); }' + 244 | 245 | '}'); 246 | 247 | // Swing out 248 | utils.inject( '@' + prefix + 'keyframes swing-out {' + 249 | 250 | '0% {' + prefix + 'transform: rotateX(0deg); }' + 251 | '30% {' + prefix + 'transform: rotateX(-30deg); }' + 252 | '60% {' + prefix + 'transform: rotateX(15deg); }' + 253 | '100% {' + prefix + 'transform: rotateX(0deg); }' + 254 | 255 | '}'); 256 | 257 | // Swing in 258 | utils.inject( '@' + prefix + 'keyframes swing-in {' + 259 | 260 | '0% {' + prefix + 'transform: rotateX(0deg); }' + 261 | '50% {' + prefix + 'transform: rotateX(-10deg); }' + 262 | '90% {' + prefix + 'transform: rotateX(15deg); }' + 263 | '100% {' + prefix + 'transform: rotateX(0deg); }' + 264 | 265 | '}'); 266 | 267 | // Shading (unfold) 268 | utils.inject( '@' + prefix + 'keyframes unfold-over {' + 269 | '0% { opacity: 1.0; }' + 270 | '100% { opacity: 0.0; }' + 271 | '}'); 272 | 273 | // Shading (fold) 274 | utils.inject( '@' + prefix + 'keyframes fold-over {' + 275 | '0% { opacity: 0.0; }' + 276 | '100% { opacity: 1.0; }' + 277 | '}'); 278 | 279 | // Node styles 280 | utils.inject( '.node {' + 281 | 'position: relative;' + 282 | 'display: block;' + 283 | '}'); 284 | 285 | // Face styles 286 | utils.inject( '.face {' + 287 | 'pointer-events: none;' + 288 | 'position: absolute;' + 289 | 'display: block;' + 290 | 'height: 100%;' + 291 | 'width: 100%;' + 292 | 'left: 0;' + 293 | 'top: 0;' + 294 | '}'); 295 | } 296 | 297 | // Merge options & defaults 298 | var opts = $.extend( {}, $.fn.makisu.defaults, options ); 299 | 300 | // Extract api method arguments 301 | var args = Array.prototype.slice.call( arguments, 1 ); 302 | 303 | // Main plugin loop 304 | return this.each( function () { 305 | 306 | // If the user is calling a method... 307 | if ( api[ options ] ) { 308 | return api[ options ].apply( this, args ); 309 | } 310 | 311 | // Store options in view 312 | $this = $( this ).data( opts ); 313 | 314 | // Only proceed if the scene hierarchy isn't already built 315 | if ( !$this.data( 'initialized' ) ) { 316 | 317 | $this.data( 'initialized', true ); 318 | 319 | // Select the first level of matching child elements 320 | $kids = $this.children( opts.selector ); 321 | 322 | // Build a scene graph for elements 323 | $root = $( markup.node ).addClass( 'root' ); 324 | $base = $root; 325 | 326 | // Process each element and insert into hierarchy 327 | $kids.each( function( index, el ) { 328 | 329 | $item = $( el ); 330 | 331 | // Which animation should this node use? 332 | anim = 'fold' + ( !index ? '-first' : '' ); 333 | 334 | // Since we're adding absolutely positioned children 335 | $item.css( 'position', 'relative' ); 336 | 337 | // Give the item some depth to avoid clipping artefacts 338 | $item.css(utils.prefix({ 339 | 'transform-style': 'preserve-3d', 340 | 'transform': 'translateZ(-0.1px)' 341 | })); 342 | 343 | // Create back face 344 | $back = $( markup.back ); 345 | $back.css( 'background', $item.css( 'background' ) ); 346 | $back.css(utils.prefix({ 'transform': 'translateZ(-0.1px)' })); 347 | 348 | // Create shading 349 | $over = $( markup.over ); 350 | $over.css(utils.prefix({ 'transform': 'translateZ(0.1px)' })); 351 | $over.css({ 352 | 'background': opts.shading, 353 | 'opacity': 0.0 354 | }); 355 | 356 | // Begin folded 357 | $node = $( markup.node ).append( $item ); 358 | $node.css(utils.prefix({ 359 | 'transform-origin': '50% 0%', 360 | 'transform-style': 'preserve-3d', 361 | 'animation': anim + ' 1ms linear 0s 1 normal forwards' 362 | })); 363 | 364 | // Build display list 365 | $item.append( $over ); 366 | $item.append( $back ); 367 | $base.append( $node ); 368 | 369 | // Use as parent in next iteration 370 | $base = $node; 371 | }); 372 | 373 | // Set root transform settings 374 | $root.css(utils.prefix({ 375 | 'transform-origin': '50% 0%', 376 | 'transform-style': 'preserve-3d' 377 | })); 378 | 379 | // Apply perspective 380 | $this.css(utils.prefix({ 381 | 'transform': 'perspective(' + opts.perspective + 'px)' 382 | })); 383 | 384 | // Display the scene 385 | $this.append( $root ); 386 | } 387 | }); 388 | }; 389 | 390 | // Default options 391 | $.fn.makisu.defaults = { 392 | 393 | // Perspective to apply to rotating elements 394 | perspective: 1200, 395 | 396 | // Default shading to apply (null => no shading) 397 | shading: 'rgba(0,0,0,0.12)', 398 | 399 | // Area of rotation (fraction or pixel value) 400 | selector: null, 401 | 402 | // Fraction of speed (0-1) 403 | overlap: 0.6, 404 | 405 | // Duration per element 406 | speed: 0.8, 407 | 408 | // Animation curve 409 | easing: 'ease-in-out' 410 | }; 411 | 412 | $.fn.makisu.enabled = canRun; 413 | 414 | })( jQuery ); --------------------------------------------------------------------------------