1 // FOUNDATION MOTION UI
18 // - - - - - - - - - - - - - - - - - - - - - - - - -
20 /// @Foundation.settings
22 // Classes to use when triggering in/out animations
27 $motion-class-active: (
28 in: "ng-enter-active",
29 out: "ng-leave-active",
31 $motion-class-stagger: (
32 in: "ng-enter-stagger",
33 out: "ng-leave-stagger",
35 $motion-class-showhide: (
39 $motion-class-showhide-active: (
40 in: "ng-hide-remove-active",
41 out: "ng-hide-add-active",
44 // Set if movement-based transitions should also fade the element in and out
45 $motion-slide-and-fade: false !default;
46 $motion-hinge-and-fade: true !default;
47 $motion-scale-and-fade: true !default;
48 $motion-spin-and-fade: true !default;
50 // Default speed for transitions and animations
51 $motion-duration-default: 500ms !default;
53 // Slow and fast modifiders
54 $motion-duration-slow: 750ms !default;
55 $motion-duration-fast: 250ms !default;
56 $motion-stagger-duration-default: 150ms !default;
57 $motion-stagger-duration-short: 50ms !default;
58 $motion-stagger-duration-long: 300ms !default;
60 // Default timing function for transitions and animations
61 $motion-timing-default: ease !default;
63 // Built-in and custom easing functions
64 // Every item in this map becomes a CSS class
70 easeInOut: ease-in-out,
71 bounceIn: cubic-bezier(0.485, 0.155, 0.240, 1.245),
72 bounceOut: cubic-bezier(0.485, 0.155, 0.515, 0.845),
73 bounceInOut: cubic-bezier(0.760, -0.245, 0.240, 1.245),
76 // Default delay for all transitions and animations
77 $motion-delay-default: 0 !default;
78 // Short and long delay modifiers
79 $motion-delay-short: 300ms !default;
80 $motion-delay-long: 700ms !default;
83 // Looks for a timing function in the list of presets
84 // If none are found, returns the value as-is.
85 @function get-timing($timing) {
86 @if map-has-key($motion-timings, $timing) {
87 @return map-get($motion-timings, $timing);
94 // Applies transition settings common to all mixins
95 @mixin transition-basics(
96 $duration: $motion-duration-default,
97 $timing: $motion-timing-default,
98 $delay: $motion-delay-default
100 transition-duration: $duration;
101 transition-timing-function: get-timing($timing);
102 transition-delay: $delay;
105 // Wraps content in an enter/leave class, chained to the parent selector
106 // Define the initial state of a transition here
107 @mixin transition-start($dir) {
108 $sel1: map-get($motion-class, $dir);
109 $sel2: map-get($motion-class-showhide, $dir);
117 // Wraps content in an enter/leave active class, chained to the matching
118 // enter/leave class, chained to the parent selector
119 // Define the end state of a transition here
120 @mixin transition-end($dir) {
121 $sel1: map-get($motion-class, $dir);
122 $sel1A: map-get($motion-class-active, $dir);
124 $sel2: map-get($motion-class-showhide, $dir);
125 $sel2A: map-get($motion-class-showhide-active, $dir);
127 &.#{$sel1}.#{$sel1A},
128 &.#{$sel2}.#{$sel2A} {
133 @mixin stagger($delay-amount) {
134 transition-delay: $delay-amount;
135 // this is to avoid accidental CSS inheritance
136 transition-duration:0;
140 // 1. Base Transitions
141 // - - - - - - - - - - - - - - - - - - - - - - - - -
147 $fade: $motion-slide-and-fade,
148 $duration: $motion-duration-default,
149 $timing: $motion-timing-default,
150 $delay: $motion-delay-default
153 top: translateY(-100%),
154 right: translateX(100%),
155 bottom: translateY(100%),
156 left: translateX(-100%),
162 $start: map-get($slideDirections, $from);
163 $end: translateX(0) translateY(0);
166 $start: translateX(0) translateY(0);
167 $end: map-get($slideDirections, $from);
171 @include transition-start($dir) {
172 @include transition-basics($duration, $timing, $delay);
173 transition-property: transform, opacity;
174 backface-visibility: hidden;
177 @if $fade { opacity: if($dir == in, 0, 1); }
179 @include transition-end($dir) {
182 @if $fade { opacity: if($dir == in, 1, 0); }
191 $duration: $motion-duration-default,
192 $timing: $motion-timing-default,
193 $delay: $motion-delay-default
195 @include transition-start($dir) {
196 @include transition-basics($duration, $timing, $delay);
197 transition-property: opacity;
200 @include transition-end($dir) {
210 $perspective: 2000px,
211 $turn-origin: from-back,
212 $fade: $motion-hinge-and-fade,
213 $duration: $motion-duration-default,
214 $timing: $motion-timing-default,
215 $delay: $motion-delay-default
218 // Rotation directions when hinging from back vs. front
219 $rotationAmount: 90deg;
221 top: rotateX($rotationAmount * -1),
222 right: rotateY($rotationAmount * -1),
223 bottom: rotateX($rotationAmount),
224 left: rotateY($rotationAmount),
227 top: rotateX($rotationAmount),
228 right: rotateY($rotationAmount),
229 bottom: rotateX($rotationAmount * -1),
230 left: rotateY($rotationAmount * -1),
235 @if $turn-origin == from-front {
236 $rotation: map-get($rotationsFrom, $from);
238 @else if $turn-origin == from-back {
239 $rotation: map-get($rotationsBack, $from);
242 @warn "`$turn-origin` must be either `from-back` or `from-front`";
245 // Start and end state
249 $start: perspective($perspective) $rotation;
253 $start: rotate(0deg);
254 $end: perspective($perspective) $rotation;
266 @include transition-start($dir) {
267 @include transition-basics($duration, $timing, $delay);
268 transition-property: transform, opacity;
270 transform-origin: $origin;
271 @if $fade { opacity: if($dir == in, 0, 1); }
273 @include transition-end($dir) {
275 @if $fade { opacity: if($dir == in, 1, 0); }
284 $fade: $motion-scale-and-fade,
285 $duration: $motion-duration-default,
286 $timing: $motion-timing-default,
287 $delay: $motion-delay-default
289 @include transition-start($dir) {
290 @include transition-basics($duration, $timing, $delay);
291 transition-property: transform, property;
292 transform: scale($from);
293 @if $fade { opacity: if($dir == in, 0, 1) }
295 @include transition-end($dir) {
296 transform: scale($to);
297 @if $fade { opacity: if($dir == in, 1, 0) }
306 $fade: $motion-spin-and-fade,
307 $duration: $motion-duration-default,
308 $timing: $motion-timing-default,
309 $delay: $motion-delay-default
311 $amount: turn-to-deg($amount);
316 $start: if($ccw, $amount, $amount * -1);
321 $end: if($ccw, $amount * -1, $amount);
324 @include transition-start($dir) {
325 transition-property: transform, opacity;
326 transform: rotate($start);
327 @if $fade { opacity: if($dir == in, 0, 1); }
329 @include transition-end($dir) {
330 transform: rotate($end);
331 @if $fade { opacity: if($dir == in, 1, 0); }
336 // 2. Base Animations
337 // - - - - - - - - - - - - - - - - - - - - - - - - -
341 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% {
342 transform: translateX(7%);
344 5%, 15%, 25%, 35%, 45%, 55%, 65%, 75%, 85%, 95% {
345 transform: translateX(-7%);
347 100% { transform: translateX(0); }
352 0% { transform: rotate(0deg); }
353 100% { transform: rotate(360deg); }
356 @keyframes spin-ccw {
357 0% { transform: rotate(0deg); }
358 100% { transform: rotate(-360deg); }
364 transform: rotate(7deg);
367 transform: rotate(-7deg);
369 0%, 30%, 70%, 100% { transform: rotate(0); }
374 $duration: $motion-duration-default,
375 $timing: $motion-timing-default,
376 $delay: $motion-delay-default,
380 animation-name: $animation;
381 animation-duration: $duration;
382 animation-timing-function: $timing;
384 backface-visibility: hidden;
385 transform: translate3d(0,0,0);
388 animation-delay: $delay;
390 @if $iterations != null {
391 animation-iteration-count: $iterations;
394 @if $animation == null {
395 @warn "Please include an animation name";
400 // - - - - - - - - - - - - - - - - - - - - - - - - -
402 @include exports(motion) {
408 .slideInDown { @include slide($from: top); }
409 .slideInLeft { @include slide($from: right); }
410 .slideInUp { @include slide($from: bottom); }
411 .slideInRight { @include slide($from: left); }
412 .slideOutBottom { @include slide($dir: out, $from: bottom); }
413 .slideOutRight { @include slide($dir: out, $from: right); }
414 .slideOutUp { @include slide($dir: out, $from: top); }
415 .slideOutLeft { @include slide($dir: out, $from: left); }
418 .fadeIn { @include fade(in, 0, 1); }
419 .fadeOut { @include fade(out, 1, 0); }
422 .hingeInFromTop { @include hinge($dir: in, $from: top); }
423 .hingeInFromRight { @include hinge($dir: in, $from: right); }
424 .hingeInFromBottom { @include hinge($dir: in, $from: bottom); }
425 .hingeInFromLeft { @include hinge($dir: in, $from: left); }
426 .hingeInFromMiddleX { @include hinge($dir: in, $from: top, $axis: center); }
427 .hingeInFromMiddleY { @include hinge($dir: in, $from: right, $axis: center); }
428 .hingeOutFromTop { @include hinge($dir: out, $from: top); }
429 .hingeOutFromRight { @include hinge($dir: out, $from: right); }
430 .hingeOutFromBottom { @include hinge($dir: out, $from: bottom); }
431 .hingeOutFromLeft { @include hinge($dir: out, $from: left); }
432 .hingeOutFromMiddleX { @include hinge($dir: out, $from: top, $axis: center); }
433 .hingeOutFromMiddleY { @include hinge($dir: out, $from: right, $axis: center); }
436 .zoomIn { @include scale(in, 1.5, 1); }
437 .zoomOut { @include scale(out, 0.5, 1); }
440 .spinIn { @include spin(in, 0.75turn); }
441 .spinOut { @include spin(out, 0.75turn); }
442 .spinInCCW { @include spin(in, 0.75turn, true); }
443 .spinOutCCW { @include spin(out, 0.75turn, true); }
450 .slow { transition-duration: $motion-duration-slow !important; }
451 .fast { transition-duration: $motion-duration-fast !important; }
454 @each $easing in map-keys($motion-timings) {
456 transition-timing-function: map-get($motion-timings, $easing) !important;
461 .delay { transition-delay: $motion-delay-short !important; }
462 .long-delay { transition-delay: $motion-delay-long !important; }
468 .shake { @include animation(shake); }
469 .spin-cw { @include animation(spin-cw); }
470 .spin-ccw { @include animation(spin-ccw); }
471 .wiggle { @include animation(wiggle); }
482 &.infinite { animation-iteration-count: infinite; }
485 @each $timing in map-keys($motion-timings) {
487 animation-timing-function: map-get($motion-timings, $timing) !important;
492 &.slow { animation-duration: $motion-duration-slow !important; }
493 &.fast { animation-duration: $motion-duration-fast !important; }
496 &.delay { animation-delay: $motion-delay-short !important; }
497 &.long-delay { animation-delay: $motion-delay-long !important; }
499 .stagger { @include stagger($motion-stagger-duration-default); }
500 .stort-stagger { @include stagger($motion-stagger-duration-default); }
501 .long-stagger { @include stagger($motion-stagger-duration-default); }
504 // View animation classes
505 // - - - - - - - - - - - - - - - - - - - -
507 // Applied to the immediate parent of the animating views
513 // Applied to the animating views
515 &.ng-enter-active, &.ng-leave-active {
516 position: absolute !important;
517 backface-visibility: hidden;
518 -webkit-transform-style: preserve-3d;