// Presentation styles body { padding: 4em 0; text-align: center; background: #f1f1f1; } // --------------------------------------------- // Functions // --------------------------------------------- @function scale-list ($list, $multiplier) { $return: (); @each $key in $list { $return: append($return, $key * $multiplier * 1%, comma); } @return $return; } // --------------------------------------------- // Mixins (the bulk of it) // --------------------------------------------- @mixin coverflow ($options) { // Check for required options @if map_has_key($options, "items") != true { @error "Coverflow: please provide the number of items in the coverflow."; } // Constants $STEPS: 4; // Define default options that the user may override $defaults: ( width: 200px, height: 200px, duration: 4s, className: coverflow ); // Extend the defaults with the options passed in $options: map_merge($defaults, $options); // Extracted and computed variables $selector: map-get($options, 'className'); $duration: map-get($options, 'duration'); $items: map-get($options, 'items'); $delay: $duration / $STEPS; $totalDuration: $duration + ($delay * ($items - $STEPS)); // Component .#{$selector} { width: map-get($options, 'width'); height: map-get($options, 'height'); display: inline-block; position: relative; > * { position: absolute; top: 0; left: 0; width: map-get($options, 'width'); height: map-get($options, 'height'); animation: coverflow $totalDuration ease both infinite; } @for $i from 2 through $items { :nth-child(#{$i}) { animation-delay: ($i - 1) * $delay; } } } // Items .#{$selector}-item { border-radius: 50%; border: 5px solid white; } // Calculate keyframe ranges $keyScale: $duration / $totalDuration; $keys: ( scale-list((0, 10), $keyScale): ( opacity: 0, transform: translate3d(190px, 0, 0) scale(0.6) ), scale-list((25, 35), $keyScale): ( opacity: 0.2, transform: translate3d(170px, 0, 0) scale(0.6) ), scale-list((50, 60), $keyScale): ( opacity: 1, transform: translate3d(0, 0, 0) scale(1) ), scale-list((75, 85), $keyScale): ( opacity: 0.2, transform: translate3d(-170px, 0, 0) scale(0.6) ), scale-list((0, 100), $keyScale): ( opacity: 0, transform: translate3d(-190px, 0, 0) scale(0.6) ), (100%): ( opacity: 0, transform: translate3d(-190px, 0, 0) scale(0.6) ) ); @keyframes coverflow { @each $frames, $attrs in $keys { #{$frames} { @each $key, $value in $attrs { #{$key}: $value; } } } } } // --------------------------------------------- // How to use this thang. // // You can also pass a "className" option to // change it from the default ".coverflow" // --------------------------------------------- @include coverflow(( items: 8, duration: 4s, width: 200px, height: 200px ));