背景
最近有个小需求需要点击标题展示/折叠文字,并且标题后面还跟着一个svg的下拉图标。大概的效果如下:
我记得之前是有人在掘金上分享如何实现这个下拉图标动画的(貌似不是基于svg?),但我找不到了。。。
一开始,我先去element-plus和ant-design上粗略地看了看有没有类似的下拉图标效果。但我发现貌似就element-plus的select组件上用到了下拉图标旋转的过度动画,和上面的gif预览还有点差异。
因此,我就自己稍微研究了下svg的动画,供自己学习和大家参考~
绘制svg
画一个静态下拉图标
首先,先把默认的图标用svg画出来,代码如下
这段代码大概的效果长这样:
这里最关键的就是<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"):
画一个静态折叠图标
知道下拉图标如何绘制之后,只要对称地画个折叠图标的<path>就行
这里就直接给出我的结果了d="M0 20 l15 -15 15 15"
这段路径的坐标如下
过度动画
这部分其实比较简单,两个路径d之间的过渡动画可以通过添加css的transition实现
同时,通过react添加点击切换事件
.icon{
transition: all ease-out 0.2s;
}
到此,一共30行左右的代码就实现了demo的拉下动画~
题外话:不定高文本过渡动画
由于公司在搞海外业务,导致折叠的文本会出现各种语言,使得本文的高度不固定。然而,css的transition属性无法给height: auto;的元素添加高度过渡动画。
此处,我参考了CSS 如何让auto height完美支持过渡动画?这篇文章,通过grid布局和grid-template-rows: 0fr;来解决多语言带来的不定高问题。就是兼容性没那么优秀,需要chrome 107+。
最后
开头demo的完整代码如下