路径 clip-rule="evenodd" d="M33.377 4.574a3.508 3.508 0 0 0-2.633-1.126c-1 0-1.993.67-2.604 1.334l.002-1.24-1.867-.002-.02 10.17v.133l1.877.002.008-3.18c.567.611 1.464.97 2.462.973 1.099 0 2.022-.377 2.747-1.117.73-.745 1.1-1.796 1.103-3.002.003-1.232-.358-2.222-1.075-2.945Zm-3.082.55c.637 0 1.176.23 1.602.683.438.438.663 1.012.66 1.707-.003.7-.22 1.33-.668 1.787-.428.438-.964.661-1.601.661-.627 0-1.15-.22-1.6-.666-.445-.46-.662-1.086-.662-1.789.003-.695.227-1.27.668-1.708a2.13 2.13 0 0 1 1.596-.675h.005Zm5.109-.067-.008 4.291c-.002.926.263 1.587.784 1.963.325.235.738.354 1.228.354.376 0 .967-.146.967-.146l-.168-1.564s-.43.133-.64-.01c-.198-.136-.296-.428-.296-.866l.008-4.022 1.738.002.002-1.492-1.738-.002.005-2.144-1.874-.002-.005 2.143-1.573-.002 1.57 1.497ZM20.016 1.305h-9.245l-.002 1.777h3.695l-.016 8.295v.164l1.955.002-.008-8.459 3.621-.002V1.305Z" fill="#262D3D" fill-rule="evenodd">路径><路径 clip-rule="evenodd" d="M10.06 5.844 7.277 3.166 4.015.03 2.609 1.374l2.056 1.978-4.51 4.313 6.065 5.831 1.387-1.327-2.073-1.994 4.526-4.331ZM4.274 8.7a.211.211 0 0 1-.124 0c-.04-.013-.074-.03-.15-.102l-.817-.787c-.072-.069-.092-.104-.105-.143a.187.187 0 0 1 0-.12c.013-.039.03-.07.105-.143L5.76 4.938c.072-.07.108-.09.15-.099a.21.21 0 0 1 .123 0c.041.012.075.03.15.101L7 5.727c.072.07.093.104.103.144.013.04.013.08 0 .119-.013.04-.03.072-.106.143L4.422 8.601a.325.325 0 0 1-.147.099Z" fill="#204ECF" fill-rule="evenodd">路径><路径 clip-rule="evenodd" d="M24.354 4.622a3.94 3.94 0 0 0-2.876-1.149 4.1 4.1 0 0 0-2.829 1.084c-.804.725-1.214 1.733-1.217 2.992-.002 1.26.405 2.267 1.207 2.995a4.114 4.114 0 0 0 2.832 1.094c.04.002.082.002.123.002a3.967 3.967 0 0 0 2.75-1.138c.538-.532 1.183-1.473 1.186-2.938.002-1.465-.637-2.408-1.176-2.942Zm-.59 2.94c-.003.73-.228 1.334-.671 1.794-.441.458-.99.69-1.633.69a2.166 2.166 0 0 1-1.614-.697c-.43-.45-.65-1.057-.65-1.797s.222-1.344.655-1.795a2.17 2.17 0 0 1 1.617-.69c.64 0 1.189.235 1.63.698.443.46.668 1.064.665 1.797ZM41.15 6.324c0-.458.25-1.465 1.632-1.465.49 0 .768.159 1.003.347.227.18.34.626.34.994v.174l-2.282.341C40.035 6.98 39 7.913 38.993 9.28c-.002.708.266 1.314.777 1.76.503.438 1.191.67 2.004.673 1.023 0 1.792-.354 2.341-1.084.003.31.003.621.003.91h1.903l.013-5.246c.002-.856-.289-1.685-.864-2.14-.567-.449-1.31-.679-2.386-.681h-.015c-.82 0-1.69.208-2.274.695-.689.572-1.027 1.478-1.027 2.178l1.682-.02Zm.864 3.814c-.676-.002-1.115-.371-1.112-.938.003-.589.43-.933 1.346-1.081l1.875-.305v.017c-.005 1.36-.87 2.307-2.102 2.307h-.008Zm4.917-8.712-.018 10.058v.044l1.684.005.018-10.06v-.045l-1.684-.002Zm2.654 9.491c0-.173.062-.322.19-.445a.645.645 0 0 1 .462-.186c.18 0 .338.062.465.186a.596.596 0 0 1 .193.445.583.583 0 0 1-.193.443.644.644 0 0 1-.465.183.634.634 0 0 1-.461-.183.59.59 0 0 1-.191-.443Zm.108 0c0 .146.052.273.158.376a.54.54 0 0 0 .389.154.539.539 0 0 0 .547-.53.498.498 0 0 0-.16-.373.531.531 0 0 0-.387-.156.531.531 0 0 0-.387.155.497.497 0 0 0-.16.374Zm.702.344-.176-.3h-.118v.3h-.109v-.688h.292c.144 0 .23.082.23.196 0 .096-.076.168-.176.188l.178.304h-.121Zm-.294-.596v.21h.167c.093 0 .14-.034.14-.104 0-.072-.047-.106-.14-.106h-.167Z" fill="#262D3D" fill-rule="evenodd">路径>< / svg >作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
菲利普是一名web开发人员,在高度交互式前端应用程序方面具有专业知识. 在为AlignAlytics和Captario等公司工作期间,他帮助构建了几个BI产品的数据可视化.
10
动画是网络中无处不在的一部分. 与互联网早期困扰网站的闪烁GIF图像不同, 今天的动画更加微妙和有品位. 设计师和前端专家使用它们使网站看起来更精致, 增强用户体验, 注意重要的元素, 传递信息.
Web开发人员可以从 SVG 和 CSS 创建动画而不使用外部库. 本SVG动画教程展示了如何为实际项目构建自定义动画.
在使用CSS动画svg之前,开发人员需要了解svg的内部工作原理. 幸运的是, 它类似于HTML:我们用XML语法定义SVG元素,并用CSS为它们设置样式, 就好像它们是HTML.
SVG元素专门用于绘制图形. 我们可以用
为了画一个矩形,
用于画圆圈等.svg还定义了
,
,
,
, <路径>
.
注意: 的 SVG元素的完整列表 甚至包括
,它允许您使用同步多媒体集成语言(SMIL)创建动画。. 然而,它的未来是不确定的,Chromium团队 建议 尽可能使用基于CSS或javascript的方法来动画svg.
可用的属性取决于元素,所以while
有 宽度
和 高度
属性,
元素具有 r
属性,该属性定义其半径.
虽然大多数HTML元素可以有子元素,但大多数SVG元素不能. 一个例外是group元素
,我们可以使用它来一次对多个元素应用CSS样式和转换.
元素及其属性HTML和SVG之间的另一个重要区别是我们如何定位元素,特别是通过 viewBox
属性 给定外层的 元素. 其值由四个由空格或逗号分隔的数字组成:
min-x
, min-y
, 宽度
, 高度
. 它们一起指定了我们希望浏览器呈现多少SVG图形. 该区域将被缩放以适应 视窗的定义 宽度
和 高度
的属性 元素.
当涉及到信件时,比例 宽度
和 高度
属性可能确实不同于 宽度
和 高度
部分 viewBox
属性.
默认情况下, SVG画布的长宽比将被保留,但代价是大于指定的长宽比 viewBox
,从而在视口中产生较小的、带字母框的呈现. 方法指定不同的行为 preserveAspectRatio
属性.
这使我们能够独立绘制图像,并确信无论上下文或渲染大小如何,所有元素都将正确定位.
虽然您可以手工编写SVG图像, 更复杂的图像可能需要矢量图形程序(我们的SVG动画教程演示了这两种技术). 我选择的编辑器是Affinity 设计er, 但是任何编辑器都应该为这里介绍的简单操作提供足够的功能.
CSS转换允许我们定义属性变化的速率和持续时间. 而不是立即从起始值跳到结束值, 当你用鼠标悬停在SVG圆圈上时,它的颜色会发生变化。
看笔 转换示例 作者:菲利普·德法尔(@dabrorius) on CodePen.
来定义转换 过渡
财产, 它接受我们想要转换的属性的名称, 转换的持续时间, a 过渡定时功能 (也称为缓和函数),效果开始前的延迟长度:
/*属性名|持续时间|缓动函数|延迟时间*/
过渡:margin-right 15 - ease-in-out 15;
我们可以为多个CSS属性定义过渡, 每一个都可以有单独的转换值. 然而,这种方法有两个明显的限制.
第一个限制是,当属性值发生变化时,会自动触发转换. 这在某些用例中是不方便的. 例如,我们不能有一个无限循环的动画.
第二个限制是转换总是有两个步骤:初始状态和最终状态. 我们可以延长动画的持续时间,但不能添加不同的关键帧.
这就是为什么存在一个更强大的概念:CSS动画. 使用CSS动画,我们可以有多个关键帧和一个无限循环:
看笔 动画的例子 作者:菲利普·德法尔(@dabrorius) on CodePen.
要在多个关键帧上动画CSS属性,首先我们需要使用 @keyframes
at-rule. 关键帧的时间是用相对单位(百分比)定义的,因为在这一点上, 我们还没有定义动画持续时间. 每个关键帧描述一个或多个CSS属性在那个时间点的值. CSS动画将确保关键帧之间的平滑过渡.
将具有描述的关键帧的动画应用到所需的元素上 动画
财产. 类似于 过渡
属性时,它接受一个持续时间、一个缓和函数和一个延迟.
唯一的区别是第一个参数是 @keyframes
名称而不是属性名称:
/* @keyframes name | duration | easing-function | delay */
动画:my- slide - 动画 3s线性1s;
现在我们已经对svg动画的工作原理有了基本的了解, 我们可以开始构建一个经典的动画——一个菜单切换,平滑地在一个“汉堡包”图标和一个关闭按钮(一个“X”)之间转换:
看笔 汉堡 作者:菲利普·德法尔(@dabrorius) on CodePen.
这是一个微妙但有价值的动画. 它吸引了用户的注意力,告诉他们可以使用图标关闭菜单.
我们通过创建一个有三行代码的SVG元素开始演示:
每行有两组属性. 的 x1
和 y1
表示直线起点的坐标,而 x2
和 y2
表示线尾的坐标. 我们用相对单位来设置位置. 这是一种确保图像内容调整大小以适应包含SVG元素的简单方法. 虽然这种方法在这种情况下有效, 有一个很大的缺点:我们不能维持这样定位的元素的长宽比. 为此,我们必须使用 viewBox
属性 元素.
注意,我们对SVG元素应用了CSS类. 有许多属性可以通过CSS改变, 因此,让我们对SVG元素应用一些基本样式.
我们将设置的大小 元素,并更改光标类型以表明它是可单击的. 但是要设置线条的颜色和粗细,我们将使用
中风
和 笔划宽度
属性. 你可能会用到 color
or 边境
,但不像 SVG子元素本身不是HTML元素,所以它们通常有不同的属性名:
.汉堡{
宽度:62 px;
身高:62 px;
光标:指针;
}
.汉堡__bar {
中风:白色;
笔划宽度:10%;
}
如果我们在这一点上渲染, 我们会看到这三条线都有相同的大小和位置, 完全重叠. 不幸的是,我们不能改变起始和结束的位置 独立 但是我们可以移动整个元素. 让我们移动顶部和底部的条 变换
CSS属性:
.汉堡__bar——顶级{
变换:translateY (-40%);
}
.汉堡__bar——机器人{
变换:translateY (40%);
}
通过移动Y轴上的条,我们最终得到了一个看起来不错的汉堡包.
现在是时候编写第二个状态:关闭按钮. 我们依赖于 .打开
CSS类应用于SVG元素以在两种状态之间切换. 为了使结果更易于访问,让我们将SVG封装在 元素并处理该级别上的单击.
添加和删除类的过程将由一个简单的JavaScript片段处理:
Const 汉堡 = document.querySelector(“按钮”);
汉堡.addEventListener("click", () => {
汉堡.班级名册.切换(“打开”);
});
为了生成X,我们可以应用一个不同的 变换
我们汉堡店的财产. 因为新的 变换
属性将覆盖旧的, 我们的起点将是原点, 三个杠的共用位置.
从那里, 我们可以把上面的棒子绕中心顺时针旋转45度, 逆时针旋转底部杆45度. 我们可以水平缩小中间条,直到它足够窄,可以隐藏在X的中心后面:
.打开 .汉堡__bar——顶级{
变换:旋转(45度);
}
.打开 .汉堡__bar——{中期
变换:scaleX (0.1);
}
.打开 .汉堡__bar——机器人{
变换:旋转(-45度);
}
默认情况下, 变换-origin
属性通常为 0,0
. 这意味着我们的工具条将围绕视口的左上角旋转, 但我们想让它们绕中心旋转. 要解决这个问题,让我们设置 变换-origin
财产 center
为 .汉堡__bar
class.
过渡
的 过渡
CSS属性告诉浏览器在两种不同状态的CSS属性之间平滑过渡. 在这里,我们想要将我们的更改动画化 变换
属性,该属性指示条形条的位置、方向和比例.
控件来控制转换的持续时间 过渡-duration
财产. 为了使动画和生成的SVG转换看起来更简洁,我们将持续时间设置为短的0.3秒:
.汉堡__bar {
转换属性:变换;
过渡-duration: 0.3s;
...
}
我们唯一需要的JavaScript代码就是使图标状态可切换的代码:
Const 汉堡 = document.querySelector(“按钮”);
汉堡.addEventListener("click", () => {
汉堡.班级名册.切换(“打开”);
});
在这里,我们根据其选择外部SVG元素 .沉默的
类使用 querySelector ()
. 然后,我们添加一个单击事件侦听器. 当触发单击事件时,我们切换 .是活跃的
类只能在 它本身,没有更深的层次. 因为我们让CSS动画只应用于元素
.是活跃的
类,切换该类将激活和停用动画.
作为最后一笔, 我们将把HTML主体转换为一个伸缩容器, 这将有助于我们的图标居中水平和垂直. 我们还将背景颜色更新为深灰色,图标颜色更新为白色, 为了获得光滑的“黑暗模式”外观和感觉:
身体{
显示:flex;
justify-content:中心;
对齐项目:中心;
background - color: # 222;
身高:100 vh;
}
与, 我们已经使用一些基本的CSS和一个简短的JavaScript片段构建了一个功能齐全的动画按钮. 很容易改变我们已经应用的转换来制作各种动画. 读者可以简单地派生codeen——它包含了一些额外的CSS来进行润色——并发挥创造力.
我们的汉堡菜单非常简单. 如果我们想做更复杂的东西呢? 这就是手工编码SVG变得困难的地方,矢量图形编辑软件可以提供帮助.
我们的第二个SVG动画是一个显示耳机图标的静音按钮. 当音乐是活跃的, the icon will pulsate 和 dance; when it’s 沉默的d, 该图标将被划掉:
看笔 静音按钮- 5 -红色划线 作者:菲利普·德法尔(@dabrorius) on CodePen.
绘制图标将超出本教程的范围(可能是你的工作描述)。, 我们从 预先绘制的SVG图标. 我们也想要相同的 body
样式化,就像汉堡包菜单的例子一样.
您可能希望在使用SVG代码之前清理它. 你可以用 svgo,一个开源的Node.基于js的SVG优化器工具. 这将删除不必要的元素,使代码更容易手工编辑, 为了添加类和组合不同的元素,您需要做什么.
在图像编辑软件中创建的SVG图标不太可能使用相对单位. 另外, 我们要确保图标的宽高比保持不变, 不管包含它的SVG元素的长宽比是多少. 为了实现这种级别的控制,我们将使用 viewBox
属性.
调整SVG的大小是个好主意 viewBox
可以设置一些易于使用的值吗. 在这种情况下,我把它转换成a viewBox
这是100 x 100像素.
让我们确保图标居中并且大小合适. 我们将应用 沉默的
类到我们的基本SVG元素,然后添加以下CSS样式:
.沉默的{
填充:白色;
宽度:80 px;
身高:70 px;
光标:指针;
}
在这里, 宽度
略大于 高度
为了避免动画旋转时的剪辑.
现在干净的SVG包含一个
包含三个元素的元素 <路径>
元素.
的 路径 元素允许我们绘制直线、曲线和弧线. 路径用一系列命令来描述,这些命令描述了应该如何绘制形状. 由于我们的图标由三个互不相连的形状组成,我们有三条路径来描述它们.
的 g SVG元素是用于对其他SVG元素进行分组的容器. 我们用它来应用脉动和舞蹈 同时对所有三条路径进行转换, 而不是单独用CSS动画SVG路径.
为了让耳机跳动和跳舞, 过渡
是不够的. 这是一个复杂到需要关键帧的例子.
在这种情况下, 我们的开始和结束关键帧(0%和100%的动画), 分别)使用稍微缩小的耳机图标. 对于动画的前40%,我们将图像稍微扩大并倾斜5度. 然后,对于下一个40%的动画,我们将其缩小到0.9x,把它旋转到另一边5度. 最后, 在动画的最后20%, 图标转换返回到相同的初始参数,以便顺利循环.
@keyframes pulse {
0% {
变换:规模(0.9);
}
40% {
变换:缩放(1)旋转(5度);
}
80% {
变换:缩放(1)旋转(-5度);
}
100% {
变换:规模(0.9)旋转(0);
}
}
为了展示关键帧是如何工作的,我们将关键帧CSS设置得过于冗长. 有三种方法可以缩短它.
因为我们的 100%
关键帧设置整个 变换
列表,如果我们省略的话 旋转()
总的来说,它的值默认为0:
100% {
变换:规模(0.9);
}
其次,我们知道我们想要 0%
和 100%
关键帧匹配因为我们在循环动画. 通过用相同的CSS规则定义它们, 如果我们想要改变动画循环中的共享点,我们不需要记住同时修改它们:
0%, 100% {
变换:规模(0.9);
}
最后,我们很快就会申请 变换:规模(0.9);
到 沉默的__headphones
类,当我们这样做时,我们根本不需要定义开始和结束关键帧! 它们将默认使用静态样式 沉默的__headphones
.
现在我们已经定义了动画关键帧,我们可以应用动画了. 我们加上 .沉默的__headphones
类到。
元素,使其影响耳机图标的所有三个部分. 首先,我们再次设定 变换-origin
to center
因为我们想让图标绕中心旋转. 我们还缩放它,使其大小与初始动画关键帧匹配. 如果没有这个步骤,从静态的“静音”图标切换到动画图标总是会导致 体型的突然增大. (无论哪种方式, 切换回静音将导致缩放跳变,如果用户在缩放大于0时单击,可能也会旋转.9x. 我们不能单独使用CSS来实现这种效果.)
我们使用 动画
CSS属性,但仅当 .是活跃的
父类存在,类似于我们如何动画汉堡包菜单.
.沉默的__headphones {
变换-origin:中心;
变换:规模(0.9);
}
.是活跃的 .沉默的__headphones {
动画:脉冲2s无限;
}
让我们在状态之间切换所需的JavaScript也遵循与汉堡包菜单相同的模式:
const 沉默的Button =文档.querySelector(“.静音”);
沉默的Button.addEventListener("click", () => {
沉默的Button.班级名册.切换(“活跃”);
});
我们将添加的下一个部分是当图标处于非活动状态时出现的划线. 由于这是一个简单的设计元素,我们可以手动编写它. 这就是拥有简单合理的地方 viewBox
价值是有用的. 我们知道画布的边缘是0和100,所以很容易计算出线的开始和结束位置:
可以使用相对单位而不是调整图像的大小. 这适用于我们的示例,因为我们只在图标上添加了简单的SVG行.
在实际场景中,您可能希望组合来自多个不同来源的更复杂的SVG内容. 这就是使它们都具有统一尺寸的有用之处, 因为我们不能像在示例中那样手动硬编码相对值.
因为我们直接对划线应用了一个类
元素,我们可以通过CSS设置样式. 我们只需要确保当图标处于活动状态时,这一行是不可见的:
.沉默的__strikethrough {
中风:红色;
透明度:0.8;
笔划宽度:12 px;
}
.是活跃的 .沉默的__strikethrough {
透明度:0;
}
可选地,我们可以添加 .是活跃的
类直接转换为SVG. 这将使动画在页面加载时立即开始, 因此,我们有效地将图标的初始状态从非动画(静音)更改为动画(非静音).
我们只触及了表面 CSS动画技术 和 视区是如何工作的. 了解如何手工编写SVG代码以保持简单的动画是值得的, 但知道如何以及何时使用外部编辑器创建的图形也很重要. 而现代浏览器使我们能够 创造令人印象深刻的动画 只使用内置功能, 对于(非常)复杂的用例, 开发人员可能想要探索动画库,比如 GSAP or 动漫.js.
动画不一定要为奢侈的项目保留. 现代CSS动画技术使我们能够在一个简单的操作中创建一系列引人入胜的动画, 困难.
特别感谢 迈克Zeballos 对于本文的技术回顾!
SVG(可缩放矢量图形)是一种基于xml的标记语言,用于描述矢量图像. 浏览器可以以这种方式清晰地渲染任何大小的图像——创建完美的清晰边缘,没有任何模糊. 另外, 与光栅图像相比,svg往往要小得多, 哪一个可以帮助网站加载更快.
SVG(可缩放矢量图形)是一种矢量图像格式, 这使得它成为用户界面元素的理想选择, 标志, 图标, 图, 类似的图像. 在这些情况下, 它将提供比PNG版本的图像更好的图像质量和更小的文件大小. SVG几乎总是更好的选择.
是的. SVG是一种矢量图像格式,其语法与HTML非常相似, 这使得制作动画更方便. 使用DOM选择器来定位各种SVG元素,并使用CSS或JavaScript将它们动画化.
有几种方法可以使SVG图像动画化. 对于中等复杂的动画, 最直接的方法是使用CSS过渡或CSS动画. 对于更复杂的情况, 你可以使用原生JavaScript动画或外部库,如GSAP或动漫.js.
菲利普是一名web开发人员,在高度交互式前端应用程序方面具有专业知识. 在为AlignAlytics和Captario等公司工作期间,他帮助构建了几个BI产品的数据可视化.
10
世界级的文章,每周发一次.
世界级的文章,每周发一次.