在本文中,我们将仅使用CSS探索Web上的动画世界。我们将首先使用SVG和CSS组合创建一个简单的动画。然后,我们将仅使用HTML和CSS创建另外两个动画。我们还将讨论何时需要将JavaScript付诸行动以及CSS的局限性。
到本文结尾,您将能够使用CSS来创建动画,从而支持使用JavaScript。您还可以识别何时需要使用JavaScript创建动画。
为了充分利用本文,假定您至少具有CSS和HTML的核心知识。
绘画效果动画
这是令人印象深刻的动画,看似易于创建。下面是我们的目标的屏幕截图。
我们首先需要为徽标创建SVG:
<svg xmlns="http://www.w3.org/2000/svg" width="279.15" height="343.95" overflow="visible" stroke="#000" stroke-width="1">
<path d="M110.57 248.64c-22.7-21.25-45.06-42.09-67.31-63.06-11.73-11.06-23.32-22.26-34.87-33.51C-2.6 141.35-2.86 128 8.02 117.42 47.67 78.82 87.46 40.35 127.21 1.84c.46-.44 1.03-.77 2.47-1.84 12.52 13.66 25.06 27.34 37.1 40.47-4.44 4.76-10.06 11.31-16.21 17.33-22.69 22.2-45.56 44.22-68.34 66.32-7.89 7.66-7.97 13.48.11 21.07 19.38 18.19 38.85 36.29 58.37 54.33 7.53 6.96 7.75 12.42.32 19.64-10.01 9.72-20.05 19.4-30.46 29.48z"/>
<path d="M150.02 343.95c-13.41-13.03-26.71-25.97-40.2-39.08 1.23-1.32 2.19-2.44 3.24-3.46 27.8-26.95 55.61-53.89 83.42-80.83 8.32-8.05 8.41-13.92-.01-21.79-19.54-18.27-39.14-36.47-58.77-54.63-6.52-6.04-6.76-12.11-.37-18.33 10.24-9.96 20.52-19.87 31.15-30.16 6.33 5.89 12.53 11.58 18.65 17.37 27.53 26.03 55.07 52.05 82.52 78.16 12.57 11.96 12.66 24.78.33 36.75-38.99 37.85-78.04 75.64-117.07 113.45-.82.79-1.71 1.51-2.89 2.55z"/>
</svg>
这是设置了SVG的笔。随意分叉它,以便您可以按照以下步骤进行操作。
设置好SVG后,我们现在将设置fill-opacity
为0
。我们稍后将对此进行动画处理:
svg {
fill-opacity: 0;
}
现在,我们可以集中精力绘制SVG。我们将通过使用CSSstroke-dashoffset
和stroke-dasharray
属性来实现。
该stroke-dasharray
属性控制用于使笔划成为路径的间隙和破折号的模式。例如,stroke-dasharray: 10
将其应用于SVG中的路径会产生虚线效果,其笔划和间隙长度为十个像素:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>绘制</title>
<style>
svg {
fill-opacity: 0;
}
svg path {
stroke-dasharray: 10;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="279.15" height="343.95" overflow="visible" stroke="#000" stroke-width="1">
<path d="M110.57 248.64c-22.7-21.25-45.06-42.09-67.31-63.06-11.73-11.06-23.32-22.26-34.87-33.51C-2.6 141.35-2.86 128 8.02 117.42 47.67 78.82 87.46 40.35 127.21 1.84c.46-.44 1.03-.77 2.47-1.84 12.52 13.66 25.06 27.34 37.1 40.47-4.44 4.76-10.06 11.31-16.21 17.33-22.69 22.2-45.56 44.22-68.34 66.32-7.89 7.66-7.97 13.48.11 21.07 19.38 18.19 38.85 36.29 58.37 54.33 7.53 6.96 7.75 12.42.32 19.64-10.01 9.72-20.05 19.4-30.46 29.48z"/>
<path d="M150.02 343.95c-13.41-13.03-26.71-25.97-40.2-39.08 1.23-1.32 2.19-2.44 3.24-3.46 27.8-26.95 55.61-53.89 83.42-80.83 8.32-8.05 8.41-13.92-.01-21.79-19.54-18.27-39.14-36.47-58.77-54.63-6.52-6.04-6.76-12.11-.37-18.33 10.24-9.96 20.52-19.87 31.15-30.16 6.33 5.89 12.53 11.58 18.65 17.37 27.53 26.03 55.07 52.05 82.52 78.16 12.57 11.96 12.66 24.78.33 36.75-38.99 37.85-78.04 75.64-117.07 113.45-.82.79-1.71 1.51-2.89 2.55z"/>
</svg>
</body>
</html>
现在,对于我们在此处创建的动画,我们希望间隙和破折号的长度与相同path
。也就是说,徽标轮廓的整个长度可以被认为是"一个破折号",并且间隙也将是轮廓的整个长度。这个想法是,我们将从徽标轮廓作为间隙开始,然后在轮廓中以破折号进行动画处理。
但是徽标的轮廓多长时间?解决此问题的一种简单方法是设置长度。让我们通过添加pathLength="1"
到每个路径来编辑SVG代码:
…
<path pathLength="1" d="M110.57 … >
…
这使绘制动画更加容易。现在我们已经设置了pathLength
,我们还stroke-dasharray
可以1
在CSS中将设置为:
svg path {
stroke-dasharray: 1;
}
现在,这里似乎没有任何变化,但这没关系。徽标各部分的整个路径现在只是一个很大的破折号。(您可以通过pathLength="1"
从其中一条路径中删除来进行试验。它会突然变成1px虚线和间隙的虚线。)
现在stroke-dashoffset
,我们可以使用,它指定我们应该开始到破折号模式的距离。在我们的例子中,我们要设置stroke-dashoffset
到1
,所以我们开始一个gap
,而不是一个dash
。由于每个间隙的长度都是的整个长度path
,因此我们现在将看到一个空白屏幕:
svg path {
stroke-dasharray: 1;
stroke-dashoffset: 1;
}
现在,我们可以有生stroke-dashoffset
回0
,这将给绘图效果:
svg path {
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: draw 2s forwards;
}
@keyframes draw {
from {
stroke-dashoffset: 1;
}
to {
stroke-dashoffset: 0;
}
}
有了这个,我们现在有了这个:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
svg {
fill-opacity: 0;
}
svg path {
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: draw 2s forwards;
}
@keyframes draw {
from {
stroke-dashoffset: 1;
}
to {
stroke-dashoffset: 0;
}
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="279.15" height="343.95" overflow="visible" stroke="#000" stroke-width="1">
<path pathLength="1" d="M110.57 248.64c-22.7-21.25-45.06-42.09-67.31-63.06-11.73-11.06-23.32-22.26-34.87-33.51C-2.6 141.35-2.86 128 8.02 117.42 47.67 78.82 87.46 40.35 127.21 1.84c.46-.44 1.03-.77 2.47-1.84 12.52 13.66 25.06 27.34 37.1 40.47-4.44 4.76-10.06 11.31-16.21 17.33-22.69 22.2-45.56 44.22-68.34 66.32-7.89 7.66-7.97 13.48.11 21.07 19.38 18.19 38.85 36.29 58.37 54.33 7.53 6.96 7.75 12.42.32 19.64-10.01 9.72-20.05 19.4-30.46 29.48z" />
<path pathLength="1" d="M150.02 343.95c-13.41-13.03-26.71-25.97-40.2-39.08 1.23-1.32 2.19-2.44 3.24-3.46 27.8-26.95 55.61-53.89 83.42-80.83 8.32-8.05 8.41-13.92-.01-21.79-19.54-18.27-39.14-36.47-58.77-54.63-6.52-6.04-6.76-12.11-.37-18.33 10.24-9.96 20.52-19.87 31.15-30.16 6.33 5.89 12.53 11.58 18.65 17.37 27.53 26.03 55.07 52.05 82.52 78.16 12.57 11.96 12.66 24.78.33 36.75-38.99 37.85-78.04 75.64-117.07 113.45-.82.79-1.71 1.51-2.89 2.55z" />
</svg>
</body>
</html>
要完成动画,我们只需要对我们的动画fill-opacity
:
svg {
width: 40%;
fill-opacity: 0;
// we set a delay of 2s so it won't start until our drawing is finished
animation: fadeOpacity 2s forwards 2s;
}
@keyframes fadeOpacity {
from {
fill-opacity: 0;
}
to {
fill-opacity: 1;
}
}
现在,我们有了最终的动画:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
svg {
width: 40%;
fill-opacity: 0;
animation: fadeOpacity 2s forwards 2s;
}
svg path {
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: draw 2s forwards;
}
@keyframes draw {
from {
stroke-dashoffset: 1;
}
to {
stroke-dashoffset: 0;
}
}
@keyframes fadeOpacity {
from {
fill-opacity: 0;
}
to {
fill-opacity: 1;
}
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="279.15" height="343.95" overflow="visible" stroke="#000" stroke-width="1">
<path pathLength="1" d="M110.57 248.64c-22.7-21.25-45.06-42.09-67.31-63.06-11.73-11.06-23.32-22.26-34.87-33.51C-2.6 141.35-2.86 128 8.02 117.42 47.67 78.82 87.46 40.35 127.21 1.84c.46-.44 1.03-.77 2.47-1.84 12.52 13.66 25.06 27.34 37.1 40.47-4.44 4.76-10.06 11.31-16.21 17.33-22.69 22.2-45.56 44.22-68.34 66.32-7.89 7.66-7.97 13.48.11 21.07 19.38 18.19 38.85 36.29 58.37 54.33 7.53 6.96 7.75 12.42.32 19.64-10.01 9.72-20.05 19.4-30.46 29.48z" />
<path pathLength="1" d="M150.02 343.95c-13.41-13.03-26.71-25.97-40.2-39.08 1.23-1.32 2.19-2.44 3.24-3.46 27.8-26.95 55.61-53.89 83.42-80.83 8.32-8.05 8.41-13.92-.01-21.79-19.54-18.27-39.14-36.47-58.77-54.63-6.52-6.04-6.76-12.11-.37-18.33 10.24-9.96 20.52-19.87 31.15-30.16 6.33 5.89 12.53 11.58 18.65 17.37 27.53 26.03 55.07 52.05 82.52 78.16 12.57 11.96 12.66 24.78.33 36.75-38.99 37.85-78.04 75.64-117.07 113.45-.82.79-1.71 1.51-2.89 2.55z" />
</svg>
</body>
</html>
我敢打赌,这比您想象的要容易得多!我知道stroke-dashoffset
和stroke-dasharray
属性可能会有些混乱,但是当您将path
长度设置为时1
,使用它们会容易得多。
这是CSS与SVG结合的强大功能的简单示例。现在,让我们在下一个示例中进一步进行介绍。
CSS蜡烛动画
因此,在最后一个示例中,我们使用SVG时有点作弊。在下一个示例中,我们将仅使用CSS(当然还有HTML)。
通过此动画,我们将使用一些基本的CSS绘图。然后,我们将使用CSS创建触发事件。最后,我们将模拟火焰(尽我们所能!)。