One day Harry Roberts had a piece of code on his web site that was being consulted on Twitter and, if possible, improved in some ways. Harry Roberts did the carousel animation using keyframes, so using some mathematical calculations is likely to improve accordingly.
"Why do we have to learn algebra, Miss?" We ' re never going to use it ... '-everyone in my maths class BIT.LY/UAM2WF
What's a good idea?
As far as I can see, Harry Roberts used a carousel animation on his homepage. You can use CSS, why use JavaScript, you know. So he uses CSS animations to make carousel animations. This may sound like a good idea, but you don't think so until you need to calculate keyframe.
Here's a description of Harry Roberts ' carousel animation.
Rolling Carousel (hard code, a bit disgusting!) and use a small animation (this animation motion is fuzzy/animated). The entire carousel animation needs to compute the transition and latency time (for example, 100%):
n * x + (n-1) * y = 100
where n refers to the number of slides, X is the percentage of the animation in the static, and Y is the percentage of the animation in motion.
This animation has 5 slides, according to the above description, you can get:
5 * x + (5-1) * y = 100
If we know the values of x and N, we can calculate the value of y:
(M-(n * x))/(n-1) = y
Assuming that X chooses a value of 17.5 (that is, the 17.5% position in the animation), we know n=5, so that we can calculate the y=3.125:
(100-(5 * 17.5))/(5-1) = 3.125
Frames transition from 17.5% to 3.125% and so on, until 100%.
If we set the X to 15, we can calculate the y=6.25:
(100-(5 * 15))/(5-1) = 6.25
If Y movement is from "Zero-or-below", it also means that we have chosen the X value too large.
Notice that we also have a middle point, which is in the middle transition frame, this number can be derived from:
(A * x) + ((A-1) * y) + (Y/2)
The problem is which frame is the middle frame in n frames. The general situation is between 3 and 4:
(3 * 17.5) + ((3-1) * 3.125) + (3.125/2) = 60.3125
This is really confusing.
The end result is:
@keyframes carousel { 0% { transform: translate3d (0,
 0, 0);
filter: blur (0);
 &NBSP} 17.5% { transform: translate3d (0, 0, 0);
filter: blur (0);  &NBSP} 19.0625% { filter: blur (2px); } 20.625% { transform: translate3d ( -20%, 0, 0);
filter: blur (0);  &NBSP} 38.125% { transform: translate3d ( -20%, 0,
0);
filter: blur (0);  &NBSP} 39.6875% { filter: blur (2px); }
41.25% { transform: translate3d ( -40%, 0, 0); filter: bluR (0);  &NBSP} 58.75% { transform: translate3d (-40%,
 0, 0);
filter: blur (0);  &NBSP} 60.3125% { filter: blur (2px); } 61.875% { transform: translate3d ( -60%, 0, 0);
filter: blur (0);  &NBSP} 79.375% { transform: translate3d ( -60%, 0,
 0);
filter: blur (0);  &NBSP} 80.9375% { filter: blur (2px); }
82.5% { transform: translate3d ( -80%, 0, 0);
filter: blur (0);  &NBSP} 100% { transform: Translate3d ( -80%, 0, 0);
filter: blur (0);  &NBSP}}
clean css animations
Before I considered sass, reduce animation code. From the code block above, it's not hard to see that there are some keyframes that are the same. This allows us to clean up the code and make the entire animation simpler:
@keyframes carousel { 0%, 17.5% { transform:
Translate3d (0, 0, 0);
filter: blur (0);  &NBSP} 19.0625% { filter: blur (2px); } 20.625%, 38.125% { transform: translate3d ( -20%, 0,
 0);
filter: blur (0);  &NBSP} 39.6875% { filter: blur (2px); } 41.25%, 58.75% { transform: translate3d ( -40%, 0, 0
);
filter: blur (0);  &NBSP} 60.3125% { filter: blur (2px); } 61.875%, 79.375% { transform: translate3d ( -60%, 0,
 0); filter: bLur (0);  &NBSP} 80.9375% { filter: blur (2px); }
82.5%, 100% { transform: translate3d ( -80%, 0, 0);
filter: blur (0);  &NBSP}}
Sass How to play
KeyFrames can usually be optimized. Because the looping frames in the @keyframes are usually very easy to produce duplicate animations. We can try.
First, to maintain consistency, we use Harry's variable name: N,x and y as usual. Don't forget the meaning of them:
$n is the number of frames in the animation
$x is the percentage of the animation frame, logically less than or equal to 100%/$n
$y is the ratio of each frame in the animation
$n: 5;
$x: 17.5%;
$y: (100%-$n * $x)/($n-1);
Now we do a loop in the @keyframes:
@keyframes Carousel {
@for $i from 0 to $n {//0, 1, 2, 3, 4
Sass Animation
}
}
In the loop, we use Harry's formula to calculate each pair of keyframes (for example, 41.25% and 58.75%):
$current-frame: ($i * $x) + ($i * $y);
$next-frame: (($i + 1) * $x) + ($i + $y);
Special statement: The parentheses can be omitted completely, here just use them to keep the code cleaner.
Now, we use these variables to generate keyframes, and don't forget to insert the correct CSS inside (there are more sass content, you can click here):
#{$current-frame, $next-frame} {
Transform:translatex ($i * -100%/$frames);
Filter:blur (0);
}
Very simple, isn't it? After running the first loop, compile the CSS code:
0%, 17.5% {
Transform:translate3d (0%, 0, 0);
Filter:blur (0);
}
The rest is what Harry said, adding the blur () effect to the middle frame. We can use his formula to figure out:
$halfway-frame: $i * ($x/1%) + ($i-1) * $y + ($y/2);
#{$halfway-frame} {
Filter:blur (2px);
}
There's been a mistake here.
Invalid CSS: We expect keyframes, such as 10%, that can be computed by-1.5625%.
As you can see, we end up with a negative keyframe. This is prohibited in the CSS specification, and even in sass it is a mistake, so we need to make sure that it doesn't happen. In fact, it only happens when $i is 0. Therefore, there is an easy way to prevent such a thing from happening, outputting $i values according to the rule:
@if $i > 0 {
#{$halfway-frame} {
Filter:blur (2px);
}
}
Error solved, this is the last code:
$n: 5;
$x: 17.5%;
$y: (100% - $n * $x) / ($n - 1); @keyframes carousel { @for $i from 0 to $n {
$current-frame: ($i * $x) + ($i * $y);
$next-frame: (($i + 1) * $x) + ($i + $y); #{$current-frame, $next-frame} {
Transform: translate3d ($i * -100% / $frames, 0, 0);    &NBSP} $halfway-frame: $i * ($x / 1%)
+ ($i - 1) * $y + ($y / 2); @if $i > 0 { #{$ halfway-frame} { filter: blur (2px); } } }
Put it all in a mixin.
So far, it's all right? Harry's animated code worked well, so he didn't compute it again. If he wants to change the slide from 5 to 4, or if he wants the animation to be faster or slower, it's time to start over.
At present our variables will contaminate the whole range. Similarly, if you need to carousel animations elsewhere, you will need to reset the other variable names and then copy the animated content to the new animation. This is by no means an ideal practice.
This is the reason why we use mixin. To make things easier to understand, we use the actual variable names to replace these letters:
$n change to $frames.
$x change to $static.
$y change to $animating.
In addition, to ensure that it outputs different moves, you can use Mixin to invoke different parameters multiple times. So we need to add one more parameter: the name of the animation.
@mixin carousel-animation ($frames, $static, $name: ' Carousel ') {
$animating: (100%-$frames * $static)/($frames- 1);
Moar Sass
}
Because mixin can be invoked in different places, to prevent the selector from including it, you can use @at-root to ensure that the animation output is at the root level:
@mixin carousel-animation ($frames, $static, $name: ' Carousel ') {
$animating: (100%-$frames * $static)/($frames- 1);
@at-root {
@keyframes #{$name} {
//Animation logic here
}
}
}
In practice, you can call this:
@include carousel-animation (
$frames: 5,
$static: 17.5%
);
Compiled CSS:
@keyframes carousel { 0%, 17.5% { transform: Translatex (0%); filter: blur (0); 19.0625% {
filter: blur (2px);
 &NBSP} 20.625%, 38.125% { transform: translatex (-20%);
filter: blur (0);  &NBSP} 39.6875% { filter: blur (2px); } 41.25%, 58.75% { transform: translatex ( -40%);
filter: blur (0);  &NBSP} 60.3125% { filter: blur (2px); } 61.875%, 79.375% { transform: translatex ( -60%);
filter: blur (0);  &NBSP} 80.9375% { filter: blur (2px);
 &NBSP} 82.5%, 100% { transform: translatex (-80%);
filter: blur (0);  &NBSP}}
The mission is complete. If we want to use another move on the contact page, we can use this:
@include carousel-animation (
$name: ' carousel-contact ',
$frames: 3,
$static: 20%
);
is not very perfect. (^_^).
Summarize
This wants to be perfect. Harry's original code is easy to read, but it's not very easy to maintain. Using Sass's automated calculations and looping features can be better and easier. Of course, it also makes the code more complex, but it also makes it easy to maintain and update. It is also very simple to use.
Sass
----// sass (V3.4.0.RC.1)// compass (v1.0.0.alpha.20)// ----/** * Generate the carousel animation * based on the number of Frames * and the pourcentage of a frame spent static * * @param {Number} $n - number of frames * @param {number}
$x - percentage of the animation spent static per frame * @param {String} $animation-name (' Carousel ') - animation name
* * @mixin carousel-animation ($frames, $static, $animation-name: ' Carousel ') { // Make ' $static ' a percentage in case it ' s unitless
@if unitless ($static) { $static: percentage ($static); } // compute the percentage of animation spent animating for each frame $animating: (100% - $frames * $static) / (
$frames - 1); // output the animation at root level //
 TO MAKE SURE IT DOESN ' T crash if called in a selector @at-root { // Create an
Animation @keyframes #{$animation-name} { // loop over the frames @for $i from 0 to $frames { // compute keyframes $current-frame: $i * $static + $i * $animating; $next-frame: ($i + 1) * $static
+ $i * $animating; $halfway-frame: $i * $static / 1%
+ ($i - 1) * $animating + $animating / 2; // output halfway styles for blur // avoid a negative keyframes by making sure ' $i ' is at least ' 1 ' @if $i > 0 { #{$halfway-frame} {
filter: blur (2px); } } // output styles for each frame #{$current-frame, $next-frame} {
transform: translatex ($i * -100% / $frames);
filter: blur (0); } }  }// generate animation @include carousel-animation (5, 17.5%);
CSS
/** * generate the carousel animation * based on the number of frames * and the pourcentage of a frame spent Static * * @param {Number} $n - number of frames * @ param {number} $x - percentage of the animation spent static per frame * @param {String} $animation-name (' Carousel ') - Animation name */@keyframes carousel { 0%, 17.5% { transform: translatex (0%); filter: blur (0); } 19.0625% { filter: blur (2px); } 20.625%, 38.125%
{ transform: translatex ( -20%); filter: blur (0); } 39.6875% { filter: blur (2px); } 41.25%, 58.75% { transform: translatex ( -40%); filter:
Blur (0);  &NBSP} 60.3125% { filter: blur (2px); } 61.875%, 79.375% { transform: translatex ( -60%);
filter: blur (0);  &NBSP} 80.9375% { filter: blur (2px); } 82.5%, 100% { transform: translatex ( -80%);
Filter: blur (0);  &NBSP}}