SVG-30行代码实现下拉图标动画

429 阅读3分钟

背景

最近有个小需求需要点击标题展示/折叠文字,并且标题后面还跟着一个svg的下拉图标。大概的效果如下:

录屏2024-09-28-10.54.41.gif

我记得之前是有人在掘金上分享如何实现这个下拉图标动画的(貌似不是基于svg?),但我找不到了。。。

一开始,我先去element-plusant-design上粗略地看了看有没有类似的下拉图标效果。但我发现貌似就element-plus的select组件上用到了下拉图标旋转的过度动画,和上面的gif预览还有点差异。

因此,我就自己稍微研究了下svg的动画,供自己学习和大家参考~

绘制svg

画一个静态下拉图标

首先,先把默认的图标用svg画出来,代码如下

2.png

这段代码大概的效果长这样:

截屏2024-09-28 11.24.43.png

这里最关键的就是<path>标签的d属性:M0 10 l15 15 15 -15
M即move to的简写,L即line to的简写,详细的参数可见深入理解SVG之Path

M0 10表示移动到坐标(0, 10)
l15 15表示从当前位置绘制一条线到(0+15, 10+15)=(15, 25)
15 -15表示从当前位置绘制一条线到(15+15, 25-15)=(30, 10)

大致的坐标如下(记住画布的大小viewBox="0 0 30 30"):

down.png

画一个静态折叠图标

知道下拉图标如何绘制之后,只要对称地画个折叠图标的<path>就行
这里就直接给出我的结果了d="M0 20 l15 -15 15 15"
这段路径的坐标如下

up.png

过度动画

这部分其实比较简单,两个路径d之间的过渡动画可以通过添加css的transition实现
同时,通过react添加点击切换事件

.icon{
  transition: all ease-out 0.2s;
}

1.png

到此,一共30行左右的代码就实现了demo的拉下动画~

题外话:不定高文本过渡动画

由于公司在搞海外业务,导致折叠的文本会出现各种语言,使得本文的高度不固定。然而,css的transition属性无法给height: auto;的元素添加高度过渡动画。

此处,我参考了CSS 如何让auto height完美支持过渡动画?这篇文章,通过grid布局和grid-template-rows: 0fr;来解决多语言带来的不定高问题。就是兼容性没那么优秀,需要chrome 107+。

最后

开头demo的完整代码如下