Update JSON API
[src/app-framework-demo.git] / afm-client / bower_components / foundation-apps / scss / components / _motion.scss
1 // FOUNDATION MOTION UI\r
2 // Table of Contents\r
3 //\r
4 // 0. Variables\r
5 // 1. Base Transitions\r
6 //      a. Slide\r
7 //      b. Fade\r
8 //      c. Hinge\r
9 //      d. Scale\r
10 //      e. Spin\r
11 // 2. Base Animations\r
12 //      a. Shake\r
13 //      b. Spinners\r
14 //      c. Wiggle\r
15 // 3. HTML Attributes\r
16 \r
17 // 0. Variables\r
18 // - - - - - - - - - - - - - - - - - - - - - - - - -\r
19 \r
20 /// @Foundation.settings\r
21 // Motion UI\r
22 // Classes to use when triggering in/out animations\r
23 $motion-class: (\r
24   in: "ng-enter",\r
25   out: "ng-leave",\r
26 ) !default;\r
27 $motion-class-active: (\r
28   in: "ng-enter-active",\r
29   out: "ng-leave-active",\r
30 ) !default;\r
31 $motion-class-stagger: (\r
32   in: "ng-enter-stagger",\r
33   out: "ng-leave-stagger",\r
34 ) !default;\r
35 $motion-class-showhide: (\r
36   in: "ng-hide-remove",\r
37   out: "ng-hide-add",\r
38 );\r
39 $motion-class-showhide-active: (\r
40   in: "ng-hide-remove-active",\r
41   out: "ng-hide-add-active",\r
42 );\r
43 \r
44 // Set if movement-based transitions should also fade the element in and out\r
45 $motion-slide-and-fade: false !default;\r
46 $motion-hinge-and-fade: true !default;\r
47 $motion-scale-and-fade: true !default;\r
48 $motion-spin-and-fade: true !default;\r
49 \r
50 // Default speed for transitions and animations\r
51 $motion-duration-default: 500ms !default;\r
52 \r
53 // Slow and fast modifiders\r
54 $motion-duration-slow: 750ms !default;\r
55 $motion-duration-fast: 250ms !default;\r
56 $motion-stagger-duration-default: 150ms !default;\r
57 $motion-stagger-duration-short: 50ms !default;\r
58 $motion-stagger-duration-long: 300ms !default;\r
59 \r
60 // Default timing function for transitions and animations\r
61 $motion-timing-default: ease !default;\r
62 \r
63 // Built-in and custom easing functions\r
64 // Every item in this map becomes a CSS class\r
65 $motion-timings: (\r
66   linear: linear,\r
67   ease: ease,\r
68   easeIn: ease-in,\r
69   easeOut: ease-out,\r
70   easeInOut: ease-in-out,\r
71   bounceIn: cubic-bezier(0.485, 0.155, 0.240, 1.245),\r
72   bounceOut: cubic-bezier(0.485, 0.155, 0.515, 0.845),\r
73   bounceInOut: cubic-bezier(0.760, -0.245, 0.240, 1.245),\r
74 ) !default;\r
75 \r
76 // Default delay for all transitions and animations\r
77 $motion-delay-default: 0 !default;\r
78 // Short and long delay modifiers\r
79 $motion-delay-short: 300ms !default;\r
80 $motion-delay-long: 700ms !default;\r
81 ///\r
82 \r
83 // Looks for a timing function in the list of presets\r
84 // If none are found, returns the value as-is.\r
85 @function get-timing($timing) {\r
86   @if map-has-key($motion-timings, $timing) {\r
87     @return map-get($motion-timings, $timing);\r
88   }\r
89   @else {\r
90     @return $timing;\r
91   }\r
92 }\r
93 \r
94 // Applies transition settings common to all mixins\r
95 @mixin transition-basics(\r
96   $duration: $motion-duration-default,\r
97   $timing: $motion-timing-default,\r
98   $delay: $motion-delay-default\r
99 ) {\r
100   transition-duration: $duration;\r
101   transition-timing-function: get-timing($timing);\r
102   transition-delay: $delay;\r
103 }\r
104 \r
105 // Wraps content in an enter/leave class, chained to the parent selector\r
106 // Define the initial state of a transition here\r
107 @mixin transition-start($dir) {\r
108   $sel1: map-get($motion-class, $dir);\r
109   $sel2: map-get($motion-class-showhide, $dir);\r
110 \r
111   &.#{$sel1},\r
112   &.#{$sel2} {\r
113     @content;\r
114   }\r
115 }\r
116 \r
117 // Wraps content in an enter/leave active class, chained to the matching\r
118 // enter/leave class, chained to the parent selector\r
119 // Define the end state of a transition here\r
120 @mixin transition-end($dir) {\r
121   $sel1:  map-get($motion-class, $dir);\r
122   $sel1A: map-get($motion-class-active, $dir);\r
123 \r
124   $sel2:  map-get($motion-class-showhide, $dir);\r
125   $sel2A: map-get($motion-class-showhide-active, $dir);\r
126 \r
127   &.#{$sel1}.#{$sel1A},\r
128   &.#{$sel2}.#{$sel2A} {\r
129     @content;\r
130   }\r
131 }\r
132 \r
133 @mixin stagger($delay-amount) {\r
134   transition-delay: $delay-amount;\r
135   // this is to avoid accidental CSS inheritance\r
136   transition-duration:0;\r
137 }\r
138 \r
139 \r
140 // 1. Base Transitions\r
141 // - - - - - - - - - - - - - - - - - - - - - - - - -\r
142 \r
143 // SLIDE\r
144 @mixin slide (\r
145   $dir: in,\r
146   $from: left,\r
147   $fade: $motion-slide-and-fade,\r
148   $duration: $motion-duration-default,\r
149   $timing: $motion-timing-default,\r
150   $delay: $motion-delay-default\r
151 ) {\r
152   $slideDirections: (\r
153     top:    translateY(-100%),\r
154     right:  translateX(100%),\r
155     bottom: translateY(100%),\r
156     left:   translateX(-100%),\r
157   );\r
158   $start: '';\r
159   $end: '';\r
160 \r
161   @if $dir == in {\r
162     $start: map-get($slideDirections, $from);\r
163     $end: translateX(0) translateY(0);\r
164   }\r
165   @else {\r
166     $start: translateX(0) translateY(0);\r
167     $end: map-get($slideDirections, $from);\r
168   }\r
169 \r
170   // CSS Output\r
171   @include transition-start($dir) {\r
172     @include transition-basics($duration, $timing, $delay);\r
173     transition-property: transform, opacity;\r
174     backface-visibility: hidden;\r
175     transform: $start;\r
176 \r
177     @if $fade { opacity: if($dir == in, 0, 1); }\r
178   }\r
179   @include transition-end($dir) {\r
180     transform: $end;\r
181 \r
182     @if $fade { opacity: if($dir == in, 1, 0); }\r
183   }\r
184 }\r
185 \r
186 // FADE\r
187 @mixin fade(\r
188   $dir: in,\r
189   $from: 0,\r
190   $to: 1,\r
191   $duration: $motion-duration-default,\r
192   $timing: $motion-timing-default,\r
193   $delay: $motion-delay-default\r
194 ) {\r
195   @include transition-start($dir) {\r
196     @include transition-basics($duration, $timing, $delay);\r
197     transition-property: opacity;\r
198     opacity: $from;\r
199   }\r
200   @include transition-end($dir) {\r
201     opacity: $to;\r
202   }\r
203 }\r
204 \r
205 // HINGE\r
206 @mixin hinge (\r
207   $dir: in,\r
208   $from: left,\r
209   $axis: edge,\r
210   $perspective: 2000px,\r
211   $turn-origin: from-back,\r
212   $fade: $motion-hinge-and-fade,\r
213   $duration: $motion-duration-default,\r
214   $timing: $motion-timing-default,\r
215   $delay: $motion-delay-default\r
216 ) {\r
217 \r
218   // Rotation directions when hinging from back vs. front\r
219   $rotationAmount: 90deg;\r
220   $rotationsBack: (\r
221     top: rotateX($rotationAmount * -1),\r
222     right: rotateY($rotationAmount * -1),\r
223     bottom: rotateX($rotationAmount),\r
224     left: rotateY($rotationAmount),\r
225   );\r
226   $rotationsFrom: (\r
227     top: rotateX($rotationAmount),\r
228     right: rotateY($rotationAmount),\r
229     bottom: rotateX($rotationAmount * -1),\r
230     left: rotateY($rotationAmount * -1),\r
231   );\r
232 \r
233   // Rotation origin\r
234   $rotation: '';\r
235   @if $turn-origin == from-front {\r
236     $rotation: map-get($rotationsFrom, $from);\r
237   }\r
238   @else if $turn-origin == from-back {\r
239     $rotation: map-get($rotationsBack, $from);\r
240   }\r
241   @else {\r
242     @warn "`$turn-origin` must be either `from-back` or `from-front`";\r
243   }\r
244 \r
245   // Start and end state\r
246   $start: '';\r
247   $end: '';\r
248   @if $dir == in {\r
249     $start: perspective($perspective) $rotation;\r
250     $end: rotate(0deg);\r
251   }\r
252   @else {\r
253     $start: rotate(0deg);\r
254     $end: perspective($perspective) $rotation;\r
255   }\r
256 \r
257   // Turn axis\r
258   $origin: '';\r
259   @if $axis == edge {\r
260     $origin: $from;\r
261   }\r
262   @else {\r
263     $origin: center;\r
264   }\r
265 \r
266   @include transition-start($dir) {\r
267     @include transition-basics($duration, $timing, $delay);\r
268     transition-property: transform, opacity;\r
269     transform: $start;\r
270     transform-origin: $origin;\r
271     @if $fade { opacity: if($dir == in, 0, 1); }\r
272   }\r
273   @include transition-end($dir) {\r
274     transform: $end;\r
275     @if $fade { opacity: if($dir == in, 1, 0); }\r
276   }\r
277 }\r
278 \r
279 // SCALE\r
280 @mixin scale(\r
281   $dir: in,\r
282   $from: 1.5,\r
283   $to: 1,\r
284   $fade: $motion-scale-and-fade,\r
285   $duration: $motion-duration-default,\r
286   $timing: $motion-timing-default,\r
287   $delay: $motion-delay-default\r
288 ) {\r
289   @include transition-start($dir) {\r
290     @include transition-basics($duration, $timing, $delay);\r
291     transition-property: transform, property;\r
292     transform: scale($from);\r
293     @if $fade { opacity: if($dir == in, 0, 1) }\r
294   }\r
295   @include transition-end($dir) {\r
296     transform: scale($to);\r
297     @if $fade { opacity: if($dir == in, 1, 0) }\r
298   }\r
299 }\r
300 \r
301 // SPIN\r
302 @mixin spin(\r
303   $dir: in,\r
304   $amount: 0.75turn,\r
305   $ccw: false,\r
306   $fade: $motion-spin-and-fade,\r
307   $duration: $motion-duration-default,\r
308   $timing: $motion-timing-default,\r
309   $delay: $motion-delay-default\r
310 ) {\r
311   $amount: turn-to-deg($amount);\r
312   $start: 0;\r
313   $end: 0;\r
314 \r
315   @if $dir == in {\r
316     $start: if($ccw, $amount, $amount * -1);\r
317     $end: 0;\r
318   }\r
319   @else {\r
320     $start: 0;\r
321     $end: if($ccw, $amount * -1, $amount);\r
322   }\r
323 \r
324   @include transition-start($dir) {\r
325     transition-property: transform, opacity;\r
326     transform: rotate($start);\r
327     @if $fade { opacity: if($dir == in, 0, 1); }\r
328   }\r
329   @include transition-end($dir) {\r
330     transform: rotate($end);\r
331     @if $fade { opacity: if($dir == in, 1, 0); }\r
332   }\r
333 }\r
334 \r
335 \r
336 // 2. Base Animations\r
337 // - - - - - - - - - - - - - - - - - - - - - - - - -\r
338 \r
339 // SHAKE\r
340 @keyframes shake {\r
341   0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% {\r
342     transform: translateX(7%);\r
343   }\r
344   5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% {\r
345     transform: translateX(-7%);\r
346   }\r
347   100% { transform: translateX(0); }\r
348 }\r
349 \r
350 // SPINNERS\r
351 @keyframes spin-cw {\r
352   0% { transform: rotate(0deg); }\r
353   100% { transform: rotate(360deg); }\r
354 }\r
355 \r
356 @keyframes spin-ccw {\r
357   0% { transform: rotate(0deg); }\r
358   100% { transform: rotate(-360deg); }\r
359 }\r
360 \r
361 // WIGGLE\r
362 @keyframes wiggle {\r
363   40%, 50%, 60% {\r
364     transform: rotate(7deg);\r
365   }\r
366   35%, 45%, 55%, 65% {\r
367     transform: rotate(-7deg);\r
368   }\r
369   0%, 30%, 70%, 100% { transform: rotate(0); }\r
370 }\r
371 \r
372 @mixin animation(\r
373   $animation,\r
374   $duration: $motion-duration-default,\r
375   $timing: $motion-timing-default,\r
376   $delay: $motion-delay-default,\r
377   $iterations: null\r
378 ) {\r
379   \r
380   animation-name: $animation;\r
381   animation-duration: $duration;\r
382   animation-timing-function: $timing;\r
383 \r
384   backface-visibility: hidden;\r
385   transform: translate3d(0,0,0);\r
386 \r
387   @if $delay != null {\r
388     animation-delay: $delay;\r
389   }\r
390   @if $iterations != null {\r
391     animation-iteration-count: $iterations;\r
392   }\r
393 \r
394   @if $animation == null {\r
395     @warn "Please include an animation name";\r
396   }\r
397 }\r
398 \r
399 // 3. HTML Exports\r
400 // - - - - - - - - - - - - - - - - - - - - - - - - -\r
401 \r
402 @include exports(motion) {\r
403   /*\r
404     Transitions\r
405   */\r
406 \r
407   // Slide\r
408   .slideInDown    { @include slide($from: top); }\r
409   .slideInLeft    { @include slide($from: right); }\r
410   .slideInUp      { @include slide($from: bottom); }\r
411   .slideInRight   { @include slide($from: left); }\r
412   .slideOutBottom { @include slide($dir: out, $from: bottom); }\r
413   .slideOutRight  { @include slide($dir: out, $from: right); }\r
414   .slideOutUp     { @include slide($dir: out, $from: top); }\r
415   .slideOutLeft   { @include slide($dir: out, $from: left); }\r
416 \r
417   // Fade\r
418   .fadeIn  { @include fade(in, 0, 1); }\r
419   .fadeOut { @include fade(out, 1, 0); }\r
420 \r
421   // Hinge\r
422   .hingeInFromTop      { @include hinge($dir: in, $from: top); }\r
423   .hingeInFromRight    { @include hinge($dir: in, $from: right); }\r
424   .hingeInFromBottom   { @include hinge($dir: in, $from: bottom); }\r
425   .hingeInFromLeft     { @include hinge($dir: in, $from: left); }\r
426   .hingeInFromMiddleX  { @include hinge($dir: in, $from: top,   $axis: center); }\r
427   .hingeInFromMiddleY  { @include hinge($dir: in, $from: right, $axis: center); }\r
428   .hingeOutFromTop     { @include hinge($dir: out, $from: top); }\r
429   .hingeOutFromRight   { @include hinge($dir: out, $from: right); }\r
430   .hingeOutFromBottom  { @include hinge($dir: out, $from: bottom); }\r
431   .hingeOutFromLeft    { @include hinge($dir: out, $from: left); }\r
432   .hingeOutFromMiddleX { @include hinge($dir: out, $from: top,   $axis: center); }\r
433   .hingeOutFromMiddleY { @include hinge($dir: out, $from: right, $axis: center); }\r
434 \r
435   // Scale\r
436   .zoomIn  { @include scale(in,  1.5, 1); }\r
437   .zoomOut { @include scale(out, 0.5, 1); }\r
438 \r
439   // Spin\r
440   .spinIn     { @include spin(in, 0.75turn); }\r
441   .spinOut    { @include spin(out, 0.75turn); }\r
442   .spinInCCW  { @include spin(in, 0.75turn, true); }\r
443   .spinOutCCW { @include spin(out, 0.75turn, true); }\r
444 \r
445   /*\r
446     Transition modifiers\r
447   */\r
448 \r
449   // Duration\r
450   .slow { transition-duration: $motion-duration-slow !important; }\r
451   .fast { transition-duration: $motion-duration-fast !important; }\r
452 \r
453   // Easing\r
454   @each $easing in map-keys($motion-timings) {\r
455     .#{$easing} {\r
456       transition-timing-function: map-get($motion-timings, $easing) !important;\r
457     }\r
458   }\r
459 \r
460   // Delay\r
461   .delay       { transition-delay: $motion-delay-short !important; }\r
462   .long-delay  { transition-delay: $motion-delay-long !important; }\r
463 \r
464   /*\r
465     Animations\r
466   */\r
467 \r
468   .shake    { @include animation(shake); }\r
469   .spin-cw  { @include animation(spin-cw); }\r
470   .spin-ccw { @include animation(spin-ccw); }\r
471   .wiggle   { @include animation(wiggle); }\r
472 \r
473   /*\r
474     Animation modifiers\r
475   */\r
476 \r
477   .shake,\r
478   .spin-cw,\r
479   .spin-ccw,\r
480   .wiggle {\r
481     // Repeat\r
482     &.infinite { animation-iteration-count: infinite; }\r
483 \r
484     // Easing\r
485     @each $timing in map-keys($motion-timings) {\r
486       &.#{$timing} {\r
487         animation-timing-function: map-get($motion-timings, $timing) !important;\r
488       }\r
489     }\r
490 \r
491     // Duration\r
492     &.slow { animation-duration: $motion-duration-slow !important; }\r
493     &.fast { animation-duration: $motion-duration-fast !important; }\r
494 \r
495     // Delay\r
496     &.delay       { animation-delay: $motion-delay-short !important; }\r
497     &.long-delay  { animation-delay: $motion-delay-long !important; }\r
498   }\r
499   .stagger { @include stagger($motion-stagger-duration-default); }\r
500   .stort-stagger { @include stagger($motion-stagger-duration-default); }\r
501   .long-stagger { @include stagger($motion-stagger-duration-default); }\r
502 }\r
503 \r
504 // View animation classes\r
505 // - - - - - - - - - - - - - - - - - - - -\r
506 \r
507 // Applied to the immediate parent of the animating views\r
508 .position-absolute {\r
509   overflow: hidden;\r
510   position: relative;\r
511 }\r
512 \r
513 // Applied to the animating views\r
514 .ui-animation {\r
515   &.ng-enter-active, &.ng-leave-active {\r
516     position: absolute !important;\r
517     backface-visibility: hidden;\r
518     -webkit-transform-style: preserve-3d;\r
519     top: 0;\r
520     right: 0;\r
521     bottom: 0;\r
522     left: 0;\r
523   }\r
524 }\r