Skip to main content

Animation

Free2016-12-03#CSS#CSS animation#animation-fill-mode#animation-play-state#CSS3闪烁动画

The way CSS animation is defined is very similar to Flash, involving concepts like keyframes, blank keyframes, and ordinary frames in Flash.

I. CSS Animation

CSS animation has two main advantages over JS animation:

  1. Smoothness

Because the rendering engine can use frame-skipping and other techniques to ensure performance is as smooth as possible.

  1. Browser performance optimization

By handing the animation sequence over to the browser, it can optimize performance and efficiency—for example, by reducing the refresh frequency for tabs that are not visible.

Defining an animation consists of two parts:

  • Configuring various animation sub-properties

  • Defining keyframe styles via @keyframes

The browser creates tween animations based on these, calculating interpolations to connect the various keyframes.

II. animation Sub-properties

animation-name: The keyframe name defined by @keyframes, default is none
animation-duration: Animation duration, default is 0s, identical to transition
animation-timing-function: Easing function, default is ease, identical to transition
animation-delay: Delay time, default is 0s, identical to transition
animation-iteration-count: Number of repetitions, default is 1
animation-direction: Direction, default is normal
animation-fill-mode: Style application mode, default is none
animation-play-state: Used to pause/resume the animation sequence, default is running

Note:

  • duration comes first, followed by delay; the order of other parameters is arbitrary.

  • animation-name should not be the same as keywords, as it will prioritize matching properties.

animation-iteration-count

animation-iteration-count = infinite | <number>

Animation repetition count; values represent infinite and a specific number of times respectively.

animation-direction

animation-direction = normal | reverse | alternate | alternate-reverse

Animation execution direction; values represent normal, reverse, alternate (forward on odd times, reverse on even times), and alternate-reverse (reverse on odd times, forward on even times) respectively.

animation-fill-mode

animation-fill-mode = none | forwards | backwards | both

Style application mode; values represent: no keyframe styles applied, final state style applied (after finishing), initial state style applied (during delay), and both initial state style during delay and final state style after finishing.

Note: The initial and final states could be 0% or 100%, determined jointly by animation-iteration-count and animation-direction.

Keyword meanings are as follows:

none: After the animation ends, remove the styles defined by @keyframes and restore the original styles.
forwards: After the animation ends, maintain the final state style.
backwards: Before the animation starts (during the delay), maintain the initial state style.
both: Has both forwards and backwards effects; i.e., maintains the initial state style during the delay and the final state style after the animation ends.

See the Demo for specific differences: http://www.ayqy.net/temp/animation/animation-fill-mode.html, click the red block to start the animation.

animation-play-state

animation-play-state = running | paused

Determines whether the animation is running or paused; can be used to control animation pause/resume, and is more powerful and flexible than delay.

See the Demo for the specific effect: http://www.ayqy.net/temp/animation/animation-play-state.html

III. @keyframes

Syntax is as follows:

@keyframes anmiationName {
    0% {}
    /*...*/
    100% {}
}

If 0% and 100% are not defined, the browser calculates a set of values for all properties based on keyframes at other moments.

P.S. to and from are aliases for 0% and 100% respectively. Since the initial and final states are important, they are entitled to English names.

IV. Events

transition has only one end event, while animation provides three events:

animationstart      Start
animationend        End
animationiteration  Start of the next iteration

The event object has three special properties:

  • animationName

    Which is the animation-name.

  • elapsedTime

    The unit is seconds. For animationstart and animationend, it represents the time the animation has executed up to this moment. For animationiteration, it represents the time the next iteration starts. Similar to the transitionend event, it is generally not affected by delay.

    Specifically, elapsedTime in animationstart is generally 0, unless animation-delay is a negative value, in which case elapsedTime is -1 * delay.

  • pseudoElement

    The pseudo-element name starting with ::. If the animation is not applied to a pseudo-element, it is an empty string.

Note: At the end of the last repetition, animationiteration will not be triggered; instead, animationend will be triggered.

V. Techniques

1. Using steps(1) to Remove Smooth Transitions

steps(1) is very similar to linear. Removing the tween transition of a linear animation and leaving only the keyframes, where the frames between keyframes continue the previous keyframe, results in steps(1).

When creating Flash, you first insert two keyframes. At this time, the frames between the two keyframes are ordinary frames (used to extend the display time of the previous keyframe). This is the effect of steps(1). Right-click the latter keyframe and create a tween animation, and you get the linear effect.

Example as follows:

.rgb {
    -webkit-animation: rgb 1.5s linear infinite;
    animation: rgb 1.5s linear infinite;
}
@keyframes rgb {
    0% {
        opacity: red;
    }
    33% {
        background: green;
    }
    66% {
        background: blue;
    }
}

The effect is a smooth transition of the background color between red, green, and blue. To remove the smooth transition, simply change linear to steps(1), as follows:

.rgb-step {
    -webkit-animation: rgb 1.5s steps(1) infinite;
    animation: rgb 1.5s steps(1) infinite;
}

The effect becomes switching the background color every 0.5 seconds without any gradient transition.

Specific application: Infinite switching between two states (blinking)

.blink {
    -webkit-animation: blink 1s steps(1) infinite;
    animation: blink 1s steps(1) infinite;
}
@keyframes blink {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 1;
    }
}

2. Adding Keyframes to Remove Smooth Transitions

There is another interesting way to implement the blinking effect:

.blink {
    -webkit-animation: blink 1s linear infinite;
    animation: blink 1s linear infinite;
}
@keyframes blink {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 0;
    }
    50.01% {
        opacity: 1;
    }
    100% {
        opacity: 1;
    }
}

Although it is still a linear smooth transition, the insertion of:

50.01% {
    opacity: 1;
}

removes the tween from 50% -> 100% and shifts the opacity tween to 50% -> 50.01%. In short durations, this tween change will not be noticed. Of course, if the duration is long enough, such as:

.blink {
    -webkit-animation: blink 10000s linear infinite;
    animation: blink 10000s linear infinite;
}

you should be able to see the opacity transition from 0 to 1 within a certain second. But in general, this implementation of blinking works fine in terms of effect.

3. Controlling Delay with Keyframes

animation-delay is only effective before the animation starts; it won't insert a delay for each repetition. Similar to the 50.01% technique above, you can insert a delay for each repetition by inserting blank keyframes to achieve the effect of a loading spinner waiting after each rotation:

.wait {
    -webkit-animation: wait 1s linear infinite;
    animation: wait 1s linear infinite;
}
@keyframes wait {
    0% {
        -webkit-transform: rotateZ(0);
        transform: rotateZ(0);
    }
    40% {
        -webkit-transform: rotateZ(0);
        transform: rotateZ(0);
    }
    100% {
        -webkit-transform: rotateZ(360deg);
        transform: rotateZ(360deg);
    }
}

Achieving a 0.4s wait for each rotation.

4. steps Frame-by-frame Animation

Spread the sequence frames across a single image and modify the background-position.

When implementing with steps(), you need to copy the first frame at the end (e.g., for a 6-frame animation, you need a 7-frame tiled image). For example:

.walk {
    background: url(walk.svg);
    width: 162px;
    height: 230px;

    -webkit-animation: walk 1s steps(22) infinite;
    animation: walk 1s steps(22) infinite;
}
@keyframes walk {
    0% {
        background-position: 0 0;
    }
    100% {
        background-position: -3564px 0;
    }
}

In this case, walk.svg is filled with 23 frames horizontally, with each frame sized at 162 * 230. By shifting the background image to the left, it can be shifted up to 162 * 22 = 3564, at which point the last frame (which has the same content as the first frame) is displayed, connecting the start and end.

Of course, there is another method: use steps(1) to remove smooth transitions and then manually set 22 keyframes. This is more laborious, so no example is given here, but it is certainly feasible.

Online Demo: http://www.ayqy.net/temp/animation/css-animation-tricks.html

VI. Summary

The way CSS animation is defined is very similar to Flash. For example, several concepts in Flash:

  • Keyframe: If you want the content at a certain point to be different from what preceded it, insert a keyframe.

  • Blank Keyframe: Indicates no content is present, displayed as a small white dot. It can be converted to and from a keyframe; adding content makes it a keyframe, and removing content from a keyframe makes it a blank keyframe.

  • Ordinary Frame: What follows a keyframe or a blank keyframe is an ordinary frame. An ordinary frame continues the content of the previous keyframe, so its role is to control the display time of the animation.

Think about how this corresponds to the CSS @keyframes definition. Isn't it quite interesting?

References

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment