├── 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 |
16 |
17 |
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 |
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 | */
22 | !function(e){for(var r,t,o=!1,a=document.createElement("div"),n="moz ms o webkit".split(" "),s=function(e){return e.toUpperCase()},i=0;i ',back:' ',over:' '};e.fn.makisu=function(r){if(!k){var t="Failed to detect CSS 3D support";return console&&console.warn&&(console.warn(t),this.each(function(){e(this).trigger("error",t)})),void 0}o||(o=!0,w.keyframes("unfold",{0:"transform: rotateX(180deg)",50:"transform: rotateX(-30deg)",100:"transform: rotateX(0deg)"}),w.keyframes("unfold-first",{0:"transform: rotateX(-90deg)",50:"transform: rotateX(60deg)",100:"transform: rotateX(0deg)"}),w.keyframes("fold",{0:"transform: rotateX(0deg)",100:"transform: rotateX(180deg)"}),w.keyframes("fold-first",{0:"transform: rotateX(0deg)",100:"transform: rotateX(-180deg)"}),w.keyframes("swing-out",{0:"transform: rotateX(0deg)",30:"transform: rotateX(-30deg)",60:"transform: rotateX(15deg)",100:"transform: rotateX(0deg)"}),w.keyframes("swing-in",{0:"transform: rotateX(0deg)",50:"transform: rotateX(-10deg)",90:"transform: rotateX(15deg)",100:"transform: rotateX(0deg)"}),w.keyframes("unfold-over",{0:"opacity: 1.0",100:"opacity: 0.0"}),w.keyframes("fold-over",{0:"opacity: 0.0",100:"opacity: 1.0"}),w.inject(".node {position: relative;display: block;}"),w.inject(".face {pointer-events: none;position: absolute;display: block;height: 100%;width: 100%;left: 0;top: 0;}"));var a=e.extend({},e.fn.makisu.defaults,r),n=Array.prototype.slice.call(arguments,1);return this.each(function(){return x[r]?x[r].apply(this,n):(f=e(this).data(a),f.data("initialized")||(f.data("initialized",!0),c=f.children(a.selector),d=e(b.node).addClass("root"),l=d,c.each(function(r,t){p=e(t),y="fold"+(r?"":"-first"),p.css("position","relative"),p.css(w.prefix({"transform-style":"preserve-3d",transform:"translateZ(-0.1px)"})),g=e(b.back),g.css("background",p.css("background")),g.css(w.prefix({transform:"translateZ(-0.1px)"})),u=e(b.over),u.css(w.prefix({transform:"translateZ(0.1px)"})),u.css({background:a.shading,opacity:0}),m=e(b.node).append(p),m.css(w.prefix({"transform-origin":"50% 0%","transform-style":"preserve-3d",animation:y+" 1ms linear 0s 1 normal forwards"})),p.append(u),p.append(g),l.append(m),l=m}),d.css(w.prefix({"transform-origin":"50% 0%","transform-style":"preserve-3d"})),f.css(w.prefix({transform:"perspective("+a.perspective+"px)"})),f.append(d)),void 0)})},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=k}(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 element = document.createElement( 'div' );
31 | var vendors = 'moz ms o webkit'.split( ' ' );
32 | var toupper = function( str ) { return str.toUpperCase(); };
33 |
34 | // Establish vendor prefix and CSS 3D support
35 | var vendor;
36 |
37 | for ( var prop, i = 0; i < vendors.length; i++ ) {
38 |
39 | prop = ( vendor = vendors[i] ) + 'Perspective';
40 | if ( prop in element.style || prop.replace( /^(\w)/, toupper ) in element.style ) break;
41 | }
42 |
43 | var canRun = !!vendor;
44 | var prefix = '-' + vendor + '-';
45 |
46 | var $this, $root, $base, $kids, $node, $item, $over, $back;
47 | var wait, anim, last;
48 |
49 | // Public API
50 | var api = {
51 |
52 | // Toggle open / closed
53 | toggle: function() {
54 |
55 | $this = $( this );
56 | $this.makisu( $this.hasClass( 'open' ) ? 'close' : 'open' );
57 | },
58 |
59 | // Trigger the unfold animation
60 | open: function( speed, overlap, easing ) {
61 |
62 | // Cache DOM references
63 | $this = $(this);
64 | $root = $this.find( '.root' );
65 | $kids = $this.find( '.node' ).not( $root );
66 |
67 | // Establish values or fallbacks
68 | speed = utils.resolve( $this, 'speed', speed );
69 | easing = utils.resolve( $this, 'easing', easing );
70 | overlap = utils.resolve( $this, 'overlap', overlap );
71 |
72 | $kids.each( function( index, el ) {
73 |
74 | // Establish settings for this iteration
75 | anim = 'unfold' + ( !index ? '-first' : '' );
76 | last = index === $kids.length - 1;
77 | time = speed * ( 1 - overlap );
78 | wait = index * time;
79 |
80 | // Cache DOM references
81 | $item = $( el );
82 | $over = $item.find( '.over' );
83 |
84 | // Element animation
85 | $item.css(utils.prefix({
86 | 'transform': 'rotateX(180deg)',
87 | 'animation': anim + ' ' + speed + 's ' + easing + ' ' + wait + 's 1 normal forwards'
88 | }));
89 |
90 | // Shading animation happens when the next item starts
91 | if ( !last ) wait = ( index + 1 ) * time;
92 |
93 | // Shading animation
94 | $over.css(utils.prefix({
95 | 'animation': 'unfold-over ' + (speed * 0.45) + 's ' + easing + ' ' + wait + 's 1 normal forwards'
96 | }));
97 | });
98 |
99 | // Add momentum to the container
100 | $root.css(utils.prefix({
101 | 'animation': 'swing-out ' + ( $kids.length * time * 1.4 ) + 's ease-in-out 0s 1 normal forwards'
102 | }));
103 |
104 | $this.addClass( 'open' );
105 | },
106 |
107 | // Trigger the fold animation
108 | close: function( speed, overlap, easing ) {
109 |
110 | // Cache DOM references
111 | $this = $(this);
112 | $root = $this.find( '.root' );
113 | $kids = $this.find( '.node' ).not( $root );
114 |
115 | // Establish values or fallbacks
116 | speed = utils.resolve( $this, 'speed', speed ) * 0.66;
117 | easing = utils.resolve( $this, 'easing', easing );
118 | overlap = utils.resolve( $this, 'overlap', overlap );
119 |
120 | $kids.each( function( index, el ) {
121 |
122 | // Establish settings for this iteration
123 | anim = 'fold' + ( !index ? '-first' : '' );
124 | last = index === 0;
125 | time = speed * ( 1 - overlap );
126 | wait = ( $kids.length - index - 1 ) * time;
127 |
128 | // Cache DOM references
129 | $item = $( el );
130 | $over = $item.find( '.over' );
131 |
132 | // Element animation
133 | $item.css(utils.prefix({
134 | 'transform': 'rotateX(0deg)',
135 | 'animation': anim + ' ' + speed + 's ' + easing + ' ' + wait + 's 1 normal forwards'
136 | }));
137 |
138 | // Adjust delay for shading
139 | if ( !last ) wait = ( ( $kids.length - index - 2 ) * time ) + ( speed * 0.35 );
140 |
141 | // Shading animation
142 | $over.css(utils.prefix({
143 | 'animation': 'fold-over ' + (speed * 0.45) + 's ' + easing + ' ' + wait + 's 1 normal forwards'
144 | }));
145 | });
146 |
147 | // Add momentum to the container
148 | $root.css(utils.prefix({
149 | 'animation': 'swing-in ' + ( $kids.length * time * 1.0 ) + 's ease-in-out 0s 1 normal forwards'
150 | }));
151 |
152 | $this.removeClass( 'open' );
153 | }
154 | };
155 |
156 | // Utils
157 | var utils = {
158 |
159 | // Resolves argument values to defaults
160 | resolve: function( $el, key, val ) {
161 | return typeof val === 'undefined' ? $el.data( key ) : val;
162 | },
163 |
164 | // Prefixes a hash of styles with the current vendor
165 | prefix: function( style ) {
166 |
167 | for ( var key in style ) {
168 | style[ prefix + key ] = style[ key ];
169 | }
170 |
171 | return style;
172 | },
173 |
174 | // Inserts rules into the document styles
175 | inject: function( rule ) {
176 |
177 | try {
178 |
179 | var style = document.createElement( 'style' );
180 | style.innerHTML = rule;
181 | document.getElementsByTagName( 'head' )[0].appendChild( style );
182 |
183 | } catch ( error ) {}
184 | },
185 |
186 | keyframes: function( name, frames ) {
187 |
188 | var anim = '@' + prefix + 'keyframes ' + name + '{';
189 |
190 | for ( var frame in frames )
191 |
192 | anim += frame + '%' + '{' + prefix + frames[ frame ] + ';}';
193 |
194 | utils.inject( anim + '}' );
195 | }
196 | };
197 |
198 | // Element templates
199 | var markup = {
200 | node: ' ',
201 | back: ' ',
202 | over: ' '
203 | };
204 |
205 | // Plugin definition
206 | $.fn.makisu = function( options ) {
207 |
208 | // Notify if 3D isn't available
209 | if ( !canRun ) {
210 |
211 | var message = 'Failed to detect CSS 3D support';
212 |
213 | if( console && console.warn ) {
214 |
215 | // Print warning to the console
216 | console.warn( message );
217 |
218 | // Trigger errors on elements
219 | this.each( function() {
220 | $( this ).trigger( 'error', message );
221 | });
222 | }
223 |
224 | return;
225 | }
226 |
227 | // Fires only once
228 | if ( !initialized ) {
229 |
230 | initialized = true;
231 |
232 | // Unfold
233 |
234 | utils.keyframes( 'unfold', {
235 | 0: 'transform: rotateX(180deg)',
236 | 50: 'transform: rotateX(-30deg)',
237 | 100: 'transform: rotateX(0deg)'
238 | });
239 |
240 | // Unfold (first item)
241 | utils.keyframes( 'unfold-first', {
242 | 0: 'transform: rotateX(-90deg)',
243 | 50: 'transform: rotateX(60deg)',
244 | 100: 'transform: rotateX(0deg)'
245 | });
246 |
247 | // Fold
248 | utils.keyframes( 'fold', {
249 | 0: 'transform: rotateX(0deg)',
250 | 100: 'transform: rotateX(180deg)'
251 | });
252 |
253 | // Fold (first item)
254 | utils.keyframes( 'fold-first', {
255 | 0: 'transform: rotateX(0deg)',
256 | 100: 'transform: rotateX(-180deg)'
257 | });
258 |
259 | // Swing out
260 | utils.keyframes( 'swing-out', {
261 | 0: 'transform: rotateX(0deg)',
262 | 30: 'transform: rotateX(-30deg)',
263 | 60: 'transform: rotateX(15deg)',
264 | 100: 'transform: rotateX(0deg)'
265 | });
266 |
267 | // Swing in
268 | utils.keyframes( 'swing-in', {
269 | 0: 'transform: rotateX(0deg)',
270 | 50: 'transform: rotateX(-10deg)',
271 | 90: 'transform: rotateX(15deg)',
272 | 100: 'transform: rotateX(0deg)'
273 | });
274 |
275 | // Shading (unfold)
276 | utils.keyframes( 'unfold-over', {
277 | 0: 'opacity: 1.0',
278 | 100: 'opacity: 0.0'
279 | });
280 |
281 | // Shading (fold)
282 | utils.keyframes( 'fold-over', {
283 | 0: 'opacity: 0.0',
284 | 100: 'opacity: 1.0'
285 | });
286 |
287 | // Node styles
288 | utils.inject( '.node {' +
289 | 'position: relative;' +
290 | 'display: block;' +
291 | '}');
292 |
293 | // Face styles
294 | utils.inject( '.face {' +
295 | 'pointer-events: none;' +
296 | 'position: absolute;' +
297 | 'display: block;' +
298 | 'height: 100%;' +
299 | 'width: 100%;' +
300 | 'left: 0;' +
301 | 'top: 0;' +
302 | '}');
303 | }
304 |
305 | // Merge options & defaults
306 | var opts = $.extend( {}, $.fn.makisu.defaults, options );
307 |
308 | // Extract api method arguments
309 | var args = Array.prototype.slice.call( arguments, 1 );
310 |
311 | // Main plugin loop
312 | return this.each( function () {
313 |
314 | // If the user is calling a method...
315 | if ( api[ options ] ) {
316 | return api[ options ].apply( this, args );
317 | }
318 |
319 | // Store options in view
320 | $this = $( this ).data( opts );
321 |
322 | // Only proceed if the scene hierarchy isn't already built
323 | if ( !$this.data( 'initialized' ) ) {
324 |
325 | $this.data( 'initialized', true );
326 |
327 | // Select the first level of matching child elements
328 | $kids = $this.children( opts.selector );
329 |
330 | // Build a scene graph for elements
331 | $root = $( markup.node ).addClass( 'root' );
332 | $base = $root;
333 |
334 | // Process each element and insert into hierarchy
335 | $kids.each( function( index, el ) {
336 |
337 | $item = $( el );
338 |
339 | // Which animation should this node use?
340 | anim = 'fold' + ( !index ? '-first' : '' );
341 |
342 | // Since we're adding absolutely positioned children
343 | $item.css( 'position', 'relative' );
344 |
345 | // Give the item some depth to avoid clipping artefacts
346 | $item.css(utils.prefix({
347 | 'transform-style': 'preserve-3d',
348 | 'transform': 'translateZ(-0.1px)'
349 | }));
350 |
351 | // Create back face
352 | $back = $( markup.back );
353 | $back.css( 'background', $item.css( 'background' ) );
354 | $back.css(utils.prefix({ 'transform': 'translateZ(-0.1px)' }));
355 |
356 | // Create shading
357 | $over = $( markup.over );
358 | $over.css(utils.prefix({ 'transform': 'translateZ(0.1px)' }));
359 | $over.css({
360 | 'background': opts.shading,
361 | 'opacity': 0.0
362 | });
363 |
364 | // Begin folded
365 | $node = $( markup.node ).append( $item );
366 | $node.css(utils.prefix({
367 | 'transform-origin': '50% 0%',
368 | 'transform-style': 'preserve-3d',
369 | 'animation': anim + ' 1ms linear 0s 1 normal forwards'
370 | }));
371 |
372 | // Build display list
373 | $item.append( $over );
374 | $item.append( $back );
375 | $base.append( $node );
376 |
377 | // Use as parent in next iteration
378 | $base = $node;
379 | });
380 |
381 | // Set root transform settings
382 | $root.css(utils.prefix({
383 | 'transform-origin': '50% 0%',
384 | 'transform-style': 'preserve-3d'
385 | }));
386 |
387 | // Apply perspective
388 | $this.css(utils.prefix({
389 | 'transform': 'perspective(' + opts.perspective + 'px)'
390 | }));
391 |
392 | // Display the scene
393 | $this.append( $root );
394 | }
395 | });
396 | };
397 |
398 | // Default options
399 | $.fn.makisu.defaults = {
400 |
401 | // Perspective to apply to rotating elements
402 | perspective: 1200,
403 |
404 | // Default shading to apply (null => no shading)
405 | shading: 'rgba(0,0,0,0.12)',
406 |
407 | // Area of rotation (fraction or pixel value)
408 | selector: null,
409 |
410 | // Fraction of speed (0-1)
411 | overlap: 0.6,
412 |
413 | // Duration per element
414 | speed: 0.8,
415 |
416 | // Animation curve
417 | easing: 'ease-in-out'
418 | };
419 |
420 | $.fn.makisu.enabled = canRun;
421 |
422 | })( jQuery );
--------------------------------------------------------------------------------