// Internal counter for creating unique keyframe names $-mui-custom: 0;
/// Creates a keyframe from one or more effect functions. Use this function instead of ‘mui-animation` if you want to create a keyframe animation without automatically assigning it to the element. /// @param {String} $name - Name of the keyframe. /// @param {Function} $effects… - One or more effect functions to build the keyframe with. @mixin mui-keyframes($name, $effects…) {
$obj: -mui-process-args($effects...); $obj: map-remove($obj, name); @keyframes #{$name} { // Now iterate through each keyframe percentage @each $pct, $props in $obj { #{-mui-keyframe-pct($pct)} { // Lastly, iterate through each CSS property within a percentage and print it out @each $prop, $value in $props { #{$prop}: #{$value}; } } } }
}
/// Creates a string for a CSS keyframe, by converting a list of numbers to a comma-separated list of percentage values. /// @param {Number|List} $input - List of numbers to use. /// @return {String} A set of comma-separated percentage values. /// @access private @function -mui-keyframe-pct($input) {
$output: (); @if type-of($input) == 'number' { $output: ($input * 1%); } @else if type-of($input) == 'list' { @each $i in $input { $output: append($output, ($i * 1%), comma); } } @return $output;
}
/// Prints the CSS properties from a specific key in a keyframes map. Used to borrow CSS from keyframe functions for use in transitions. /// @param {Map} $kf - Keyframe map to extract from. /// @param {Number} $key - Key in the map to print the CSS of. /// @access private @mixin -mui-keyframe-get($kf, $key) {
$map: map-get($kf, $key); @each $prop, $value in $map or () { // Some keyframe maps store transforms as quoted strings @if type-of($value) == 'string' { $value: unquote($value); } #{$prop}: $value; }
}
/// Reformats a map containing keys with a list of values, so that each key is a single value. /// @param {Map} $map - Map to split up. /// @return {Map} A reformatted map. /// @access private @function -mui-keyframe-split($map) {
$new-map: (); // Split keys with multiple values into individual keys @each $key, $item in $map { $key-type: type-of($key); @if $key-type == 'number' { $new-map: map-merge($new-map, ($key: $item)); } @else if $key-type == 'list' { @each $k in $key { $new-map: map-merge($new-map, ($k: $item)); } } } @return $new-map;
}
/// Combines a series of keyframe objects into one. /// @param {Map} $maps… - A series of maps to merge, as individual parameters. /// @return {Map} A combined keyframe object. /// @access private @function -mui-keyframe-combine($maps…) {
$new-map: (); // Iterate through each map passed in @each $map in $maps { @if type-of($map) == 'string' { $map: call($map); } $map: -mui-keyframe-split($map); // Iterate through each keyframe in the map // $key is the keyframe percentage // $value is a map of CSS properties @each $key, $value in $map { $new-value: (); @if map-has-key($new-map, $key) { // If the map already has the keyframe %, append the new property $new-value: -mui-merge-properties(map-get($new-map, $key), $value); } @else { // Otherwise, create a new map with the new property $new-value: $value; } // Finally, merge the modified keyframe value into the output map $new-map: map-merge($new-map, ($key: $new-value)); } } // Make a name for the keyframes $-mui-custom: $-mui-custom + 1 !global; $map-name: (name: 'custom-#{$-mui-custom}'); $new-map: map-merge($new-map, $map-name); @return $new-map;
}
/// Combines two maps of CSS properties into one map. If both maps have a transform property, the values from each will be combined into one property. /// @param {Map} $one - First map to merge. /// @param {Map} $two - Second map to merge. /// @return {Map} A combined map. /// @access private @function -mui-merge-properties($one, $two) {
@if map-has-key($one, transform) and map-has-key($two, transform) { $transform: join(map-get($one, transform), map-get($two, transform)); $one: map-merge($one, (transform: $transform)); $two: map-remove($two, transform); } @return map-merge($one, $two);
}