CSS 动画的魔法(以及为什么它比你想象的要简单)
对于许多开发人员(甚至是前端开发人员)来说,动画有点神秘。
但你无需成为 CSS 高手或专业的 CodePen 艺术家,也能创作出令人印象深刻的视觉效果。你日常看到的大多数动画和效果,其实只需要掌握一些技巧就能完成。
事实上,你只需花6分钟阅读本文,就能学会这些技能!(当然,你还可以再花点时间做练习。)
到最后,你就能轻松区分 atransform
和 a transition
,甚至弄清楚它们到底keyframes
是什么了。你将能够自信地组合自己的动画和效果。
就像这种类似马里奥硬币的动画:(点击一下)
动画基础
在 CSS 中,任何具有符合一定范围的值的属性都可以进行动画处理。
字体大小、颜色(因为它们位于色谱中)、屏幕位置,甚至边框半径——所有这些都具有可以在一个范围内表示的值。这与诸如 display 之类的属性形成了对比,后者具有一个封闭的潜在值列表。
display: block
和中间是什么display: none
?现在有一个脑筋急转弯!
因此,我们可以为具有一系列值的任何属性制作动画 - 其中包括该transform
属性。
什么是 CSS 变换?
变换不仅仅用于动画 - 它们是一种 CSS 属性,用于操纵事物在屏幕上的呈现方式。
你可以使用它们来执行视觉操作,例如增加对象的大小、旋转、倾斜或移动(或scale, rotate, skew, translate
)。你还可以指定仅将变换应用于特定轴。
举两个例子:transform: scale(0.5, 2)
是将对象的宽度(X 轴)减半,高度(Y 轴)加倍的简写。同样的语法也可以用来平移对象的位置:transform: translate(5px, 50px)
会将其向右移动 5px,向下移动 50px。
现在,假设这幅画是我花了一年时间练习倒立,却几乎毫无进展。如果你能帮rotate
我个忙,用 CSS 的话,我可以马上得到它Xdeg
,或者Xturn
:
解决方案:transform: rotate(90deg)
或rotate(0.5turn)
如果你想让我倒立,同时又能让我稍微高一点,该怎么办?你可以将多个变换组合到同一行。例如transform: rotate(0.5turn) scaleY(2)
。
3D变换
变换也可以在 3D 环境中操作。要创建马里奥风格的硬币动画,你需要绕其 Y 轴旋转硬币。在这种情况下,2D 旋转对圆形动画没有太大帮助(想象一下将硬币平放并旋转),因此你需要使用rotate3d
并告诉浏览器你希望它沿哪个轴移动:
语法:transform: rotate3d(x, y, z, degrees)
其中 (x,y,z) 分别为 0 到 1 之间的数字,表示轴。要将项目沿 X 轴精确旋转 90 度,可以使用:rotate3d(1, 0, 0, 90)
。
当你尝试将这枚硬币沿 Y 轴旋转 45 度时会发生什么?如果进行常规的二维旋转会怎样?如果进行90 度的三维旋转呢?
解决方案:transform: rotate3d(0, 1, 0, 45deg)
有趣的是,当我们将硬币旋转 90 度时,它就会消失。这在现实生活中是合理的——想象一下将一枚真正的硬币旋转 90 度。如果它没有深度,它就会从视野中消失。在 CSS 中,项目永远不能具有深度(或“挤压”)。我们可以通过使用perspective
父框上的属性来创建 3D 空间,然后将 Z 轴位置平移向或远离观察者(transform: translateZ(Xpx)
),但这不会创建深度——它只会将对象移近或移远。
过渡:从属性 A 到属性 B
现在,如果你想为一个项目从 A 点移动到 B 点添加动画效果,该怎么办呢?或者是一个颜色变化、旋转过渡、缩放过渡,或者其他许多可动画的 CSS 属性之一?(完整列表请见此处) 。这时,我们就需要用到transitions了。
要定义一个基本的(非关键帧)过渡,您需要告知浏览器过渡起始时刻的样式、过渡完成后的样式以及有关过渡本身的任何其他信息。例如:
示例 1 - 悬停效果
让我们创建当鼠标悬停在阳光上时产生的简单的阳光效果。
语法:要创建转换,您可以使用简写在一行中定义所有属性:
transition: border-radius 2s ease-in 5s;
或者您可以单独定义每个属性,例如:
transition-property: border-radius;
transition-duration: 2s;
transition-timing-function: ease-in;
transition-delay: 5s;
这是我们最初的阳光——把鼠标悬停在上面,你会看到光晕。但阳光看起来可不是那样的!
让我们通过为阳光的 box-shadow 属性添加过渡来创建一个漂亮的渐变阳光效果。
解决方案:transform: box-shadow 2s;
聪明的观察者会注意到,我使用了与上面硬币相同的演员;)
示例 2 - 硬币旋转
让我们回到之前的硬币,但现在我想让你添加一个旋转效果。用户点击这枚硬币,它会绕 Y 轴旋转 180 度。为此,你需要在活动状态声明一个旋转变换,并在基础状态声明一个过渡。你可以在这里用最初的硬币练习一下。
并检查您的工作或在此处查看所需的效果:(单击并按住)
注意,当活动状态移除时,动画会倒退。这是因为一旦对象不再处于活动状态,变换就会变为隐含的旋转 0。相同的过渡会重新应用,但会回到起始值。
示例 3- 加倍
让我们把两个过渡效果合并起来!要实现这个马里奥风格的硬币动画效果,你可以在一行代码中合并两个过渡效果,例如:
transition: transform 2s, padding 100s
为了使硬币的价值在上升时神奇地出现,请在透明度和顶部值上定义一个过渡。(单击并按住硬币即可查看起始效果)
解决方案:现在,如果您希望货币价值缓慢上升、出现,然后像烟雾transition: opacity 2s, top 2s;
一样迅速消失在天空中,该怎么办?
您需要对动画进行更精细的控制,您可以通过...来实现。
动画+关键帧
当我们想要对动画进行更精细的控制时,可以使用cssanimation
属性——无论是通过使用关键帧来描述效果的组成部分,还是通过设置 的其他值。与常规过渡(在对象上定义开始和结束的 CSS)不同,动画只在对象上定义开始的 CSS。之后,动画属性将接管所有 CSS 直到结束。transitions
animation
Animation
与 共享许多属性transition
,并且 - 与转换一样 - 您可以用简写或单独的属性来定义它的值。
但是,您必须提供相应的信息keyframe
:
.myObject {
animation: fancy-keyframes 5s linear;
}
你可以通过声明一个关键帧来定义关键帧@at-rule
,然后使用from
整个to
序列的百分比,或上述任何变体。例如:
@keyframes fancy-keyframes {
from {
top: 0;
opacity: 0;
}
10% {
top: 10px;
opacity: 1;
}
75% {
top: 0px;
margin-top:
}
to {
top: 200px;
opacity: 0;
}
}
至此,你应该已经掌握了构建最终烟雾升起动画所需的所有技能!回到之前的 CodePen,用关键帧来实现它,挑战一下自己吧!
这就是我们想要的效果。先别急着看 CSS!(点击并按住即可查看效果)
行业秘密:这里有一个棘手的问题,就是如何在某个点暂停动画。要做到这一点,你只需在稍后的百分比复制一个关键帧即可。:)
当然,这实际上不是抢金币的原理!我们不应该需要按住鼠标才能让动画播放到最后。有一些(非常)hacked CSS 方法可以实现这一点,但说实话,在这种情况下,我会放下我的 CSS 帽子,戴上我的 JavaScript 帽子。合适的工具适合合适的工作。
我们可以使用 React、Vue 或任何框架来实现这一点,但我们需要做的就是添加一个 onClick 类,所以我们不妨只使用原始 JS(还记得吗?)。
我们将创建一个 JavaScript 函数来添加一个类(element.classList.add(myClassName)
),然后将其添加到onClick
我们的 coin 元素中。此外,我们还会为动画添加一些动画!
现在,不用多说...点击硬币:
祝动画制作愉快!
如果您喜欢这篇文章,请查看我在egghead.io上创建的一些课程。
致谢
非常感谢Nitzan和Deb抽出时间审阅这篇文章并给出宝贵的反馈!也感谢Ofer和Diana在Lemonade Insurance制作出一些令人印象深刻的视觉效果后,给了我灵感,让我写下了这篇文章。
链接链接 https://dev.to/yoniweisbrod/the-wizardry-of-css-animations-and-why-it-s-easier-than-you-think-3j5k