css3重新开始动画
The following is a short extract from Tiffany’s new book, CSS Master, 2nd Edition.
以下是Tiffany的新书CSS Master第二版的摘录。
Think of CSS animation as the more sophisticated sister to CSS transitions. Animations differ from transitions in a few key ways:
将CSS动画视为CSS过渡的更复杂的姐妹。 动画在某些关键方面与转场不同:
- Animations don’t degrade gracefully. If there’s no support from the browser, the user is out of luck. The alternative is to use JavaScript. 动画不会优雅地降级。 如果浏览器不提供支持,则用户不走运。 替代方法是使用JavaScript。
- Animations can repeat, and repeat infinitely. Transitions are always finite. 动画可以重复,也可以无限重复。 过渡总是有限的。
- Animations use keyframes, which offer the ability to create more complex and nuanced effects. 动画使用关键帧,这些关键帧提供了创建更复杂和细微差别的效果的能力。
- Animations can be paused in the middle of the play cycle. 动画可以在播放周期的中间暂停。
The latest versions of all major browsers support CSS animations. Firefox versions 15 and earlier require a -moz-
prefix; later version don’t. Internet Explorer versions 10 and 11 also support animations without a prefix, as do all versions of Microsoft Edge.
所有主要浏览器的最新版本均支持CSS动画。 Firefox 15及更早版本需要-moz-
前缀; 更高版本没有。 Internet Explorer 10和11版本也支持不带前缀的动画,Microsoft Edge的所有版本也一样。
We can check for CSS animations support in a few ways. The first is by testing for the presence of CSSKeyframeRule
as a method of the window
object:
我们可以通过几种方式检查CSS动画的支持。 首先是通过测试是否存在CSSKeyframeRule
作为window
对象的方法:
const hasAnimations = 'CSSKeyframeRule' in window;
If the browser supports the @supports
rule and CSS.supports()
API, we can use that instead:
如果浏览器支持@supports
规则和CSS.supports()
API,我们可以改用:
const hasAnimations = CSS.supports('animation-duration: 2s');
As with transitions, we can only animate interpolatable values such as color values, lengths, and percentages.
与过渡一样,我们只能为可插值制作动画,例如颜色值,长度和百分比。
制作第一个动画 (Creating Your First Animation)
We first have to define an animation using an @keyframes
rule. The @keyframes
rule has two purposes:
我们首先必须使用@keyframes
规则定义动画。 @keyframes
规则有两个目的:
- setting the name of our animation 设置动画的名称
- grouping our keyframe rules 将关键帧规则分组
Let’s create an animation named pulse
:
让我们创建一个名为pulse
的动画:
@keyframes pulse {
}
Our keyframes will be defined within this block. In animation, a keyframe is a point at which the action changes. With CSS animations specifically, keyframe rules are used to set property values at particular points in the animation cycle. Values that fall between the values in a keyframe rule are interpolated.
我们的关键帧将在此块内定义。 在动画中, 关键帧是动作发生变化的点。 特别是对于CSS动画,关键帧规则用于在动画周期的特定点设置属性值。 插值在关键帧规则的值之间的值。
At the minimum, an animation requires two keyframes: a from
keyframe, which is the starting state for our animation, and a to
frame, which is its end state. Within each individual keyframe block, we can define which properties to animate:
动画至少需要两个关键帧:一个是from
关键帧,它是动画的开始状态,另一个是to
frame,它是动画的结束状态。 在每个关键帧块中,我们可以定义要设置动画的属性:
@keyframes pulse {
from {
transform: scale(0.5);
opacity: .8;
}
to {
transform: scale(1);
opacity: 1;
}
}
This code will scale our object from half its size to its full size, and change the opacity from 80% to 100%.
此代码会将我们的对象从其大小的一半缩放到其完整的大小,并将不透明度从80%更改为100%。
The keyframes
rule only defines an animation, though. By itself, it doesn’t make elements move. We need to apply it. Let’s also define a pulse
class that we can use to add this animation to any element:
不过, keyframes
规则仅定义了动画。 就其本身而言,它不会使元素移动。 我们需要应用它。 我们还定义一个pulse
类,可用于将该动画添加到任何元素:
.pulse {
animation: pulse 500ms;
}
Here, we’ve used the animation
shorthand property to set the animation name and duration. In order for an animation to play, we need the name of an @keyframes
rule (in this case, pulse
) and a duration. Other properties are optional.
在这里,我们使用了animation
速记属性来设置动画名称和持续时间。 为了播放动画,我们需要一个@keyframes
规则的名称(在本例中为pulse
)和一个持续时间。 其他属性是可选的。
The order of properties for animation
is similar to that of transition
. The first value that can be parsed becomes the value of animation-duration
. The second value becomes the value for animation-delay
. Words that aren’t CSS-wide keywords or animation property keyword values are assumed to be @keyframe
ruleset names.
animation
的属性顺序类似于transition
的顺序。 可以解析的第一个值成为animation-duration
的值。 第二个值成为animation-delay
的值。 不是CSS范围关键字或动画属性关键字值的@keyframe
被假定为@keyframe
规则集名称。
As with transition
, animation
also accepts an animation list. The animation list is a comma-separated list of values. We could, for example, split our pulse animation into two rules—pulse
and fade
:
与transition
, animation
也接受动画列表。 动画列表是逗号分隔的值列表。 例如,我们可以将脉冲动画分为两个规则- pulse
和fade
:
@keyframes pulse {
from {
transform: scale(0.5);
}
to {
transform: scale(1);
}
}
@keyframes fade {
from {
opacity: .5;
}
to {
opacity: 1;
}
}
Then we could combine them as part of a single animation:
然后,我们可以将它们组合为单个动画的一部分:
.pulse-and-fade {
animation: pulse 500ms, fade 500ms;
}
动画属性 (Animation Properties)
Though using the animation
property is shorter, sometimes longhand properties are clearer. Longhand animation properties are listed below:
尽管使用animation
属性的时间更短,但有时使用longhand属性的时间更清晰。 下面列出了纵向动画属性:
Property | Description | Initial value |
---|---|---|
animation-delay | How long to wait before executing the animation | 0s (executes immediately) |
animation-duration | How long the cycle of an animation should last | 0s (no animation occurs) |
animation-name | The name of an @keyframes rule | none |
animation-timing-function | How to calculate the values between the start and end states | ease |
animation-iteration-count | How many times to repeat the animation | 1 |
animation-direction | Whether or not the animation should ever play in reverse | normal (no reverse) |
animation-play-state | Whether the animation is running or paused | running |
animation-fill-mode | Specifies what property values are applied when the animation isn’t running | none |
属性 | 描述 | 初始值 |
---|---|---|
animation-delay | 执行动画之前要等待多长时间 | 0s (立即执行) |
animation-duration | 动画的周期应持续多长时间 | 0s (不发生动画) |
animation-name | @keyframes 规则的名称 | 没有 |
animation-timing-function | 如何计算开始状态和结束状态之间的值 | ease |
animation-iteration-count | 重复动画多少次 | 1个 |
animation-direction | 动画是否应该反向播放 | normal (无反向) |
animation-play-state | 动画是正在运行还是已暂停 | running |
animation-fill-mode | 指定在动画不运行时应用哪些属性值 | none |
The animation-delay
and animation-duration
properties function like transition-delay
and transition-duration
. Both accept time units as a value, either in seconds (s
) or milliseconds (ms
). Negative time values are valid for animation-delay
, but not animation-duration
.
animation-delay
和animation-duration
属性功能类似于transition-delay
和transition-duration
。 两者都接受以秒( s
)或毫秒( ms
)为单位的时间单位。 负时间值对animation-delay
有效,但对animation-duration
无效。
Let’s rewrite our .pulse
ruleset using longhand properties. Doing so gives us the following:
让我们使用长期属性重写我们的.pulse
规则集。 这样做为我们提供了以下内容:
.pulse {
animation-name: pulse;
animation-duration: 500ms;
}
The animation-name
property is fairly straightforward. Its value can be either none
or the name of the @keyframes
rule. Animation names have few restrictions. CSS keywords such as initial
, inherit
, default
, and none
are forbidden. Most punctuation characters won’t work, while letters, underscores, digits, and emojis (and other Unicode) characters usually will. For clarity and maintainability, it’s a good idea to give your animations descriptive names, and avoid using CSS properties or emojis as names.
animation-name
属性非常简单。 它的值可以是none
或@keyframes
规则的名称。 动画名称没有什么限制。 禁止使用CSS关键字,例如initial
, inherit
, default
和none
。 大多数标点符号字符无效,而字母,下划线,数字和表情符号(以及其他Unicode)字符通常无效。 为了清楚起见和可维护性,最好给动画指定描述性名称,并避免使用CSS属性或表情符号作为名称。
循环播放或不循环播放: animation-iteration-count
属性 (To Loop or Not to Loop: The animation-iteration-count
Property)
If you’re following along with your own code, you’ll notice that this animation only happens once. We want our animation to repeat. For that, we’ll need the animation-iteration-count
property.
如果遵循自己的代码,则会注意到该动画仅发生一次。 我们希望重复动画。 为此,我们需要animation-iteration-count
属性。
The animation-iteration-count
property accepts most numeric values. Whole numbers and decimal numbers are valid values. With decimal numbers, however, the animation will stop partway through the last animation cycle, ending in the to
state. Negative animation-iteration-count
values are treated the same as 1
.
animation-iteration-count
属性接受大多数数值。 整数和十进制数是有效值。 但是,使用十进制数字时,动画将在最后一个动画周期中途停止,以to
状态结束。 负的animation-iteration-count
值与1
相同。
To make an animation run indefinitely, use the infinite
keyword. The animation will play an infinite number of times. Of course, infinite
really means until the document is unloaded, the browser window closes, the animation styles are removed, or the device shuts down. Let’s make our animation infinite:
要使动画无限期运行,请使用infinite
关键字。 动画将播放无数次。 当然, infinite
实际上意味着直到文档被卸载,浏览器窗口关闭,动画样式被删除或设备关闭。 让我们使动画无限:
.pulse {
animation-name: pulse;
animation-duration: 500ms;
animation-iteration-count: infinite;
}
Or, using the animation
shorthand property:
或者,使用animation
速记属性:
.pulse {
animation: pulse 500ms infinite;
}
播放动画: animation-direction
属性 (Playing Animations: the animation-direction
Property)
There’s still a problem with our animation, however. It doesn’t so much pulse as repeat our scaling-up animation. What we want is for this element to scale up and down. Enter the animation-direction
property.
但是,我们的动画仍然存在问题。 它没有那么多脉冲作为重复我们规模的扩大动画。 我们想要的是此元素可以按比例放大和缩小。 输入animation-direction
属性。
The animation-direction
property accepts one of four values:
animation-direction
属性接受四个值之一:
normal
: the initial value, playing the animation as specifiednormal
:初始值,按指定的顺序播放动画reverse
: flips thefrom
andto
states and plays the animation in reversereverse
:翻转from
和to
状态,然后反向播放动画alternate
: plays even-numbered animation cycles in reversealternate
:反向播放偶数动画周期alternate-reverse
: plays odd-numbered animation cycles in reversealternate-reverse
:alternate-reverse
播放奇数动画周期
To continue with our current example, reverse
would scale down our object by a factor of 0.5. Using alternate
would scale our object up for the odd-numbered cycles and down for the even-numbered. Conversely, using alternate-reverse
would scale our object down for the odd-numbered cycles and up for the even ones. Since this is the effect we want, we’ll set our animation-direction
property to alternate-reverse
:
继续我们当前的示例, reverse
会将我们的对象缩小0.5倍。 使用alternate
将使我们的对象在奇数周期内放大,而在偶数周期内缩小。 相反,使用alternate-reverse
将使我们的对象按奇数循环缩小,而对偶数循环按比例缩小。 由于这是我们想要的效果,因此我们将animation-direction
属性设置为alternate-reverse
:
.pulse {
animation-name: pulse;
animation-duration: 500ms;
animation-iteration-count: infinite;
animation-direction: alternate-reverse;
}
Or, using the shorthand property:
或者,使用简写属性:
.pulse {
animation: pulse 500ms infinite alternate-reverse;
}
使用百分比关键帧 (Using Percentage Keyframes)
Our previous example was a simple pulse animation. We can create more complex animation sequences using percentage keyframes. Rather than using from
and to
, percentage keyframes indicate specific points of change over the course of the animation. Below is an example using an animation named wiggle
:
我们之前的示例是一个简单的脉冲动画。 我们可以使用百分比关键帧创建更复杂的动画序列。 百分比关键帧不是使用from
和to
,而是指示动画过程中的特定变化点。 以下是使用名为wiggle
的动画的示例:
@keyframes wiggle {
25% {
transform: scale(.5) skewX(-5deg) rotate(-5deg);
}
50% {
transform: skewY(5deg) rotate(5deg);
}
75% {
transform: skewX(-5deg) rotate(-5deg) scale(1.5);
}
100% {
transform: scale(1.5);
}
}
We’ve used increments of 25% here, but these keyframes could be 5%, 10%, or 33.2%. As the animation plays, the browser will interpolate the values between each state. As with our previous example, we can assign it to a selector:
我们在这里使用了25%的增量,但是这些关键帧可以是5%,10%或33.2%。 在播放动画时,浏览器将在每个状态之间插入值。 与前面的示例一样,我们可以将其分配给选择器:
/* Our animation will play once */
.wiggle {
animation-name: wiggle;
animation-duration: 500ms;
}
Or using the animation
shorthand property:
或使用animation
速记属性:
.wiggle {
animation: wiggle 500ms;
}
There’s just one problem here. When our animation ends, it goes back to the original, pre-animated state. To prevent this, use the animation-fill-mode
property.
这里只有一个问题。 当动画结束时,它会返回到原始的预先设置动画的状态。 为避免这种情况,请使用animation-fill-mode
属性。
animation-fill-mode
属性 (The animation-fill-mode
Property)
Animations have no effect on properties before they begin or after they stop playing. But as you’ve seen with the wiggle
example, once an animation ends, it reverts to its pre-animation state. With animation-fill-mode
, we can fill in those states before the animation starts and ends.
动画在开始播放或停止播放之后对属性没有影响。 但是,正如您在wiggle
示例中看到的那样,动画结束后,它将恢复为动画前的状态。 使用animation-fill-mode
,我们可以在动画开始和结束之前填充这些状态。
The animation-fill-mode
property accepts one of four values:
animation-fill-mode
属性接受以下四个值之一:
none
: the animation has no effect when it’s not executingnone
:不执行动画时不起作用forwards
: when the animation ends, the property values of the end state will still applyforwards
:动画结束时,结束状态的属性值仍然适用backwards
: property values for the first keyframe will be applied during the animation delay periodbackwards
:动画延迟期间将应用第一个关键帧的属性值both
: effects for bothforwards
andbackwards
applyboth
:forwards
和backwards
效果都适用
Since we want our animated element to remain in its final, scaled-up state, we’re going to use animation-fill-mode: forwards
. (animation-fill-mode: both
would also work.)
由于我们希望动画元素保持其最终的放大状态,因此我们将使用animation-fill-mode: forwards
。 ( animation-fill-mode: both
也animation-fill-mode: both
可以。)
The effect of animation-fill-mode: backwards
is most apparent when the animation-delay
property is set to 500ms
or higher. When animation-fill-mode
is set to backwards
, the property values of the first keyframe are applied, but the animation isn’t executed until the delay elapses.
当animation-delay
属性设置为500ms
或更高时, animation-fill-mode: backwards
最明显。 当animation-fill-mode
设置为backwards
,将应用第一个关键帧的属性值,但是直到延迟过去后才执行动画。
暂停动画 (Pausing Animations)
As has been mentioned, animations can be paused. Transitions can be reversed midway, or stopped altogether by toggling a class name. Animations, on the other hand, can be paused partway through the play cycle using animation-play-state
. It has two defined values—running
and paused
—and its initial value is running
.
如前所述,动画可以暂停。 转换可以在中间进行,也可以通过切换类名完全停止。 另一方面,可以使用animation-play-state
在整个播放周期中暂停animation-play-state
。 它具有两个已定义的值( running
和paused
,并且其初始值正在running
。
Let’s look at a simple example of using animation-play-state
to play or pause an animation. First, our CSS:
让我们看一个使用animation-play-state
播放或暂停动画的简单示例。 首先,我们CSS:
.wobble {
animation: wobble 3s ease-in infinite forwards alternate;
animation-play-state: paused;
}
.running {
animation-play-state: running;
}
Here, we have two declaration blocks: wobble
, which defines a wobbling animation, and running
, which sets a play state. As part of our animation
declaration, we’ve set an animation-play-state
value of paused
. To run our animation, we’ll add the running
class to our element. Let’s assume that our markup includes a Run animation button with an id
of trigger
:
在这里,我们有两个声明块: wobble
,它定义摆动的动画; running
,它设置播放状态。 作为animation
声明的一部分,我们将animation-play-state
值设置为paused
。 要运行动画,我们将running
类添加到元素中。 假设我们的标记包含id
为trigger
的“运行动画”按钮:
const trigger = document.querySelector('#trigger');
const moveIt = document.querySelector('.wobble');
trigger.addEventListener('click', function() {
moveIt.classList.toggle('running');
});
Adding .running
to our element overrides the animation-play-state
value set in .wobble
, and causes the animation to play.
添加.running
到我们的元素覆盖animation-play-state
的值设置.wobble
,并导致动画播放。
检测动画何时开始,结束或重复 (Detecting When Animations Start, End, or Repeat)
Like transitions, animations fire an event when they end: animationend
. Unlike transitions, animations also fire animationstart
and animationiteration
events when they begin to repeat. As with transitions, you might use these events to trigger another action on the page. Perhaps you’d use animationstart
to contextually reveal a Stop Animation button, or animationend
to reveal a Replay button.
像过渡一样,动画在结束时会触发一个事件: animationend
。 与过渡不同,动画在开始重复时还会触发animationstart
和animationiteration
事件。 与过渡一样,您可以使用这些事件来触发页面上的其他操作。 也许您可以使用animationstart
来根据上下文显示“ 停止动画”按钮,或者使用animationend
来显示“ 重放”按钮。
We can listen for these events with JavaScript. Below, we’re listening for the animationend
event:
我们可以使用JavaScript监听这些事件。 下面,我们正在监听animationend
事件:
const animate = document.getElementById('animate');
animate.addEventListener('animationend', function(eventObject) {
// Do something
});
Here, too, the event handler function receives an event object as its sole argument. In order to determine which animation ended, we can query the animationName
property of the event object.
在这里,事件处理函数也将事件对象作为其唯一参数。 为了确定哪个动画结束,我们可以查询事件对象的animationName
属性。
有关辅助功能的说明 (A Note About Accessibility)
Transitions and animations can enhance the user experience by making interactions smooth rather than jumpy, and otherwise bring delight to the interface. But they still have accessibility risks. Large spinning animations, for example, can cause dizziness or nausea for people with vestibular disorders, such as vertigo[5]. Flashing animations can trigger seizures in some people with photosensitive epilepsy[6]. Use them sparingly, and strongly consider giving users the ability to turn them off. We discuss one method for doing this—the prefers-reduced-motion
media query—in Chapter
过渡和动画可以使交互变得流畅而不是跳跃,从而增强用户体验,否则会给界面带来愉悦感。 但是它们仍然存在可访问性风险。 例如,大型旋转动画会导致眩晕等前庭疾病患者头晕或恶心[5]。 闪烁的动画可能会导致某些光敏性癫痫患者发作[6]。 谨慎使用它们,并强烈考虑使用户能够将其关闭。 在本章中,我们讨论一种实现此目的的方法- prefers-reduced-motion
媒体查询
关于性能的注意事项 (A Note About Performance)
Some properties create better-performing transitions and animations than others. If an animation updates a property that triggers a reflow or repaint, it may perform poorly on low-powered devices such a phones and tablets.
一些属性创建的过渡和动画效果要好于其他属性。 如果动画更新了触发重排或重绘的属性,则它在手机和平板电脑等低功耗设备上的性能可能会很差。
Properties that trigger a reflow are ones that affect layout. These include the following animatable properties:
触发重排的属性是影响布局的属性。 这些属性包括以下可设置动画的属性:
border-width
(andborder-*-width
properties)border-width
(和border-*-width
属性)border
(andborder-*
properties)border
(和border-*
属性)bottom
bottom
font-size
font-size
font-weight
font-weight
height
height
left
left
line-height
line-height
margin
(andmargin-*
properties)margin
(和margin-*
属性)min-height
min-height
min-width
min-width
max-height
max-height
max-width
max-width
padding
(andpadding-*
properties)padding
(和padding-*
属性)right
right
top
top
vertical-align
vertical-align
width
width
When these properties are animated, the browser must recalculate the size and position of the affected—and often neighboring—elements. Use transforms where you can. Transitioning or animating translation transforms (for example, transform: translate(100px,200px)
) can replace top
, left
, right
, and bottom
properties. In some cases, height
and width
animations can be replaced with a scale
transformation.
对这些属性进行动画处理后,浏览器必须重新计算受影响元素(通常是相邻元素)的大小和位置。 尽可能使用转换。 转换或设置转换转换动画(例如, transform: translate(100px,200px)
)可以替换top
, left
, right
和bottom
属性。 在某些情况下,可以用scale
转换替换height
和width
动画。
Sometimes, triggering a reflow (or layout update) is unavoidable. In those cases, minimize the number of elements affected and use tricks (such as negative delays) to shorten the perceived animation duration.
有时,不可避免地会触发重排(或布局更新)。 在这些情况下,请尽量减少受影响的元素数量,并使用技巧(例如负面延迟)来缩短感知的动画持续时间。
Properties that trigger a repaint are typically those that cause a color change. These include:
触发重新绘制的属性通常是引起颜色变化的属性。 这些包括:
background
background
background-image
background-image
background-position
background-position
background-repeat
background-repeat
background-size
background-size
border-radius
border-radius
border-style
border-style
box-shadow
box-shadow
color
color
outline
outline
outline-color
outline-color
outline-style
outline-style
outline-width
outline-width
Changes to these properties are less expensive to calculate than those that affect layout, but they do still have a cost. Changes to box-shadow
and border-radius
are especially expensive to calculate, especially for low-powered devices. Use caution when animating these properties.
与更改影响布局的属性相比,对这些属性进行的更改要便宜得多,但是它们的确要付出一定的代价。 计算box-shadow
和border-radius
更改特别昂贵,尤其是对于低功率设备而言。 设置这些属性的动画时请格外小心。
翻译自: https://www.sitepoint.com/how-to-get-started-with-css-animation/
css3重新开始动画