这是我们要创建的内容:
这是熟悉 SVG 语法和真实动画的一个很好的练习。我们将使用一个预制的 SVG 心脏,提醒自己是如何viewBox
工作的,然后添加一个 animatetransform
元素来控制跳动运动。在最初的“简单”方法之后,我们将讨论它有什么问题并进行一些改进。最后,我还将向您展示一些替代的跳动心脏动画。让我们开始!
Envato 元素上的矢量心形图标和情人节图形
我们将创建一个我们自己的简单心形图标,但如果您想更进一步,为什么不下载Envato Elements 上提供的数百个心形图形之一呢?您的每月订阅可让您无限下载字体、UI 工具包、wordpress 主题和数百万其他创意资产。看看这个!
在 Elements 上 下载数百个心脏图标和图形
1.创建一个心形图标
在您选择的矢量工具中,绘制一个简单的心形图标。它不需要是完美的,但为了方便起见,让它成为一条连续的路径。我在 100x100 像素的画布上创建了我的,几乎填满了整个东西。
如果您想使用它们,请下载我的 illustrator 和 SVG 版本。
复制并粘贴到文本编辑器中
在当今大多数矢量应用程序中,您可以复制对象并将生成的 SVG 代码粘贴到文本编辑器中。因此,对 heart 对象执行此操作。我们稍后会回到这个 SVG 片段。
2. 开始写SVG
在 Codepen(或 blanco html 文件)中,首先编写 SVG 元素的基本内容:
<svg width="100" height="100" viewBox="0 0 100 100"> </svg>
在这里,我们为 SVG 赋予了与原始画布相同的高度和宽度。我们还将 viewBox 设置为0 0 100 100
. 这意味着我们查看 SVG 的窗口从坐标 0 0(左上角)开始,尺寸为 100x100px,因此它与我们的 SVG 完美匹配。
为了提醒一下 viewBox 的工作原理,我建议您看一下 Kezz Bracey 的这个解释器:
SVG SVG 视口和视图框(适合初学者) Kezz Bracey
为了清楚地看到您正在处理的内容,添加一个 css 规则来为 SVG 背景着色:
svg { background: blue; }
让我们也使用 flexbox 将我们正在查看的内容居中:
body { height: 100vh; display: flex; align-items: center; justify-content: center; }
3. 添加心路
现在我们需要在 SVG 中嵌套一个路径元素。从空路径开始,带有fill
颜色和空d
:
<path fill="tomato" d="">
定义了一个绘制的d
路径,所以让我们添加我们的路径坐标。在您粘贴到文本编辑器中的 SVG 片段中,从d
属性中获取所有内容并将其粘贴到我们的空属性中。你应该得到一个看起来像这样的混乱字符串:
<path fill="tomato" d="M92.71,7.27L92.71,7.27c-9.71-9.69-25.46-9.69-35.18,0L50,14.79l-7.54-7.52C32.75-2.42,17-2.42,7.29,7.27v0 c-9.71,9.69-9.71,25.41,0,35.1L50,85l42.71-42.63C102.43,32.68,102.43,16.96,92.71,7.27z"> </path>
所有这些都将创建以下内容:
4. 让你的心成长
我想要一颗更大的心。
通过将 SVG 的宽度和高度属性加倍,width="200" height="200"
我们将加倍整个物体的大小。或者我们可以将所有内容缩放 150% width="150" height="150"
。或者是其他东西。我们不需要触摸 viewBox 的值,因为它们会相对于我们刚刚更改的 Viewport 保持不变。
5. 添加一点动画
为了使跳动的心脏动画化,我们将使用一个animateTransform
嵌套在 SVG 中的元素。
首先在 SVG 中添加元素,作为路径的兄弟:
<animateTransform attributeName="transform" type="scale" dur="1s" repeatCount="indefinite"> </animateTransform>
这将为父元素设置动画,即:整个 <svg>
. 这在很多情况下都不合适,最好为 中的元素设置动画,但<svg>
这种方法对我们来说效果很好。为了复习 animateTransform 的工作原理,Kezz(像往常一样)为您介绍了:
SVG 如何使用“animateTransform”进行内联 SVG 动画 Kezz Bracey
我们使用的属性是不言自明的。我们正在创建一个持续时间为 1 秒的比例变换,它将无限期地重复。
向转换添加值
现在我们需要添加一个值列表,所以它知道要设置多少动画:
<animateTransform attributeName="transform" type="scale" dur="1s" values="1; 1.5; 1.25; 1.5; 1.5; 1;" repeatCount="indefinite"> </animateTransform>
所以这里的心脏从正常大小 ( 1
) 开始,然后缩放到1.5
正常大小,然后稍微缩小到1.25
,然后回到1.5
,依此类推。这些值给了我们跳动的效果。
每个值都占用我们设置的 1 秒时间的相等部分。正如您可能想象的那样,运动似乎会加速和减速,具体取决于它需要为每一步进行多少缩放。
薰衣草色背景,我们有一个跳动的心脏动画!
6. 更好的解决方案
改变我们的方式有几个原因,第一个(重要的)原因是:这在许多移动浏览器上不起作用。ios safari 和 chrome 只会表现出一动不动的心,因为它们不喜欢animateTransform
被应用到<svg>
元素上。
“Be still my beating heart” – Sting
此外,我们正在为整个 SVG 制作动画;在内容动画<svg>
化的同时保持相同的比例会更有用。这是可能的——我们需要稍微调整一下坐标系——但这是可能的。
添加包装元素并缩小
首先将我们的<path>
和<animateTransform>
元素包装在一个组<g>
元素中。这<g>
就是现在动画的内容:
<svg> <g> <path></path> <animateTransform ></animateTransform> </g> </svg>
我还想通过增加viewBox
. 这将防止我们的心超越界限,<svg>
从而掩盖它。
<svg width="150" height="150" viewBox="0 0 200 200">
在这一点上,<svg>
再次给背景颜色是个好主意,所以我们可以看到发生了什么:
好吧,它有效,我们有一个 SVG 心跳,但坐标让我们感到困惑。group 元素从 0、0 缩放,而我们需要我们的心以某种方式从中心缩放。我们可以通过对 应用一个变换<path>
,将它的一半高度向上移动一半宽度向左移动来做到这一点:
<path transform="translate(-50 -42.5)"
这就是发生的事情:
为了补偿<path>
视口边界之外的移动,现在让我们<g>
向另一个方向偏移。我们的 viewBox 是 200x200,所以我们需要将组移动到一半:<g transform="translate(100 100)">
这就是我们的目标(如果你还在关注,那就做得很好!):
svg、path 和 g 元素相对于坐标系
或者,移动 的坐标viewBox
将具有相同的效果:
<svg width="150" height="150" viewBox="-100 -100 200 200">
如果 SVG 坐标让您头晕目眩,请查看Sara Soueidan 关于该主题的文章。
多了一个属性
为了使它与转换 一起工作<g>
,我们需要向 中添加一个属性<animateTransform>
:
additive="sum"
这有效地将我们动画中的变换值添加到<g>
自身声明的变换值中,阻止一个覆盖另一个。它可能是一个难以理解的属性,并且可能会产生一些意想不到的结果,但它在我们的案例中非常有效!
“[additive="sum"] specifies that the animation will add to the underlying value of the attribute and other lower priority animations.” – MDN
Our SVG heartbeat is complete—we’re done!
结论
我必须说实话,我喜欢这个最终结果!这是一个简单但有效的心脏跳动动画,为我们提供了练习 SVG 技能的绝佳机会。这是我们创建的(前往 CodePen 并给它一些心!)
- 复制并粘贴到文本编辑器中
- 向转换添加值
- 添加包装元素并缩小
- 多了一个属性