首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SVG 动画精髓(下)

SVG 动画精髓(下)

原创
作者头像
腾讯IVWEB团队
修改于 2017-07-07 02:24:57
修改于 2017-07-07 02:24:57
2K01
代码可运行
举报
运行总次数:1
代码可运行

本文作者:ivweb villainthr

SVG 动画精髓(上)

线条动画

SVG 中的线条动画常常用作过渡屏(splash screen)中。例如:

或者,一些比较炫酷的 LOGO 中,比如 AllowTeam 的:

看到这些炫酷的效果,大家有没有动心想学一学,看看自己到底能否做的这么好呢?

OK,我们现在来正式介绍一下线条动画。在 SVG 中,最长用到的线条标签就是 Path。这里我前面一篇文章已经做了介绍,我这里就不赘述了。

而在具体变化当中用到的是关于stroke的相关属性:(下面的属性都可以直接用在 CSS 当中!)

  • stroke*:定义笔触的颜色。例如:stroke="green"
  • stroke-dasharray:定义 dash 和 gap 的长度。它主要是通过使用 , 来分隔 实线 和 *间隔 的值。例如:stroke-dasharray="5, 5"表示,按照 实线为 5,间隔为 5 的排布重复下去。如下图:

放大看有:

另外,stroke-dasharray 并不局限于只能设置两个值,要知道,它本身的含义是设置最小重复单元,即,dash,gap,dash,gap...。比如,我定义 stroke-dasharray="15, 10, 5" 则相当于,[15,10,5] 为一段。则有:

放大看则有:

  • stroke-dashoffset*: 用来设置 dasharray 定义其实 dash 线条开始的位置。值可以为 number || percentage。百分数是相对于 SVG 的 viewport。通常结合 dasharray 可以实现线条的运动。
  • stroke-linecap: 线条的端点样式。
  • stroke-linejoin: 线条连接的样式
  • stroke-miterlimit: 一个比较复杂的概念,如果我们只是画一些一般的线段,使用上面 linejoin 即可。如果涉及对边角要求比较高的,则可以使用该属性进行定义。它的值,其实就是角长度比上线宽:

而实际理解的话,就是假设当 width 为 1。此时比例为 2。那么 miter = 2。那么超过 2 的 miter 部分则会被 cut 掉。可以参照:

他主要是配合linejoin 一起使用。因为 linejoin 默认取值就是 miter。所以,默认情况下就可以使用该标签属性。它默认值为 4。其余的大家下去实践一下即可。详细可以参考: miter

  • stroke-opacity:线段的透明度
  • stroke-width:线的粗细。

OK,介绍完关于 path 的所有 stroke 属性之后,我们就要开始动手写一下让线条动起来的代码。简单来说,就是通过stroke-dashoffsetstroke-dasharray 来做。整个动画可以分为两个过程:

  • 通过 dasharray 将实线部分隐藏,空余为全线段长。然后,将实线部分增加至全长。比如:dasharray: 0,1000变为 dasharray: 1000,1000
  • 同时,通过 dashoffset 来移动新增的实线部分,造成线段移动的效果。有:dashoffset:0,变为 dashoffset:1000

不过,这里我们不打算使用 Path 来做啥复杂的动画,这主要考虑到手头没有一些 SVG 生成工具。所以,这里我们就以 Text 来做吧(因为做起来真的简单)。

这里,先以 IV-WEB 这段文字来做动画。

先给大家看一下最终结果:

那么这种动画是怎么做的呢?

这里,我主要介绍一下关于 CSS 相关,SVG 就一个 Text 我直接贴代码了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <svg viewBox="0 0 1320 300">

  <!-- Symbol -->
  <symbol id="s-text">
    <text text-anchor="middle"
          x="50%" y="50%" dy=".35em">
      IV-WEB
    </text>
  </symbol>  

  <!-- Duplicate symbols -->
  <use xlink:href="#s-text" class="text"
       ></use>
  <use xlink:href="#s-text" class="text"
       ></use>
  <use xlink:href="#s-text" class="text"
       ></use>


</svg>

上面是通过创建一个居中定位的字体,然后使用 3 个 text 重叠。具体 CSS 我们下面来说一下。首先,我们营造的效果是从无到有,就需要使用dasharray 将 gap 设置的足够大。这里我取 300 即可。 stroke-dasharray: 0 300;

然后,通过nth-child 选择器,给每一个文字使用不同的颜色值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.text:nth-child(3n + 1) {
  stroke: #F60A0A;
}
.text:nth-child(3n + 2) {
  stroke: #F2FF14;
}

.text:nth-child(3n + 3) {
  stroke: #FB9505;
}

下面才是重点内容。此时,这 3 个 text 的起始点重合。我现在既要他们在运行时不完全重合,又要他们的线条能进行滚动。不啰嗦了,直接看代码吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@keyframes stroke {
  100% {
    stroke-dashoffset: 1000;
    stroke-dasharray: 80 160;
  }
}

@keyframes stroke1 {
  100% {
    stroke-dashoffset: 1080;
    stroke-dasharray: 80 160;
  }
}


@keyframes stroke2 {
  100% {
    stroke-dashoffset: 1160;
    stroke-dasharray: 80 160;
  }
}

这就是上面 3 个不同的 text 运用的动画。dashoffet 由 0 到 1000。这完成了滚动的目的。同时,为了让字体不重合,我还需要在对应字体的 dashoffset 上,加上不同的间隔距离。比如,第一个字体 offset 为 1000。那么第二个字体,我需要加上前一个字体 dash 的长度,即,80。所以,第二个字体就变为 1080。那么第三个就是加上前两个的dash 长度,即 1160。

大致过程就是这样,详情可以查看: IVWEB 线条动画

这里再给大家布置一个练习作业,如何实现无线连续的分段动画呢?

具体效果如图:

给点提示:

将多个文字重叠,取不同的 offset 和 array 即可。动画的终止位置一般取一个 gap + dash 的周期长即可。

后面看看这篇文章反响如何,到时候再决定是否再写一篇续集,介绍该作业的原理。

SVG 文字

在 SVG 中定义文字直接使用text 标签即可。关于文字来说,一般而言需要注意的点就那么即可,文字的排列,间距等等。这些都可以直接使用 CSS 进行控制。不过,有几个属性比较特殊,这里需要额外提一下。

text-anchor

用来定义参考点和实际字符之间的定位关系。格式为:

  • text-anchor: start | middle | end | inherit

直接看代码解释吧:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <!-- Anchors in action -->
    <text text-anchor="start"
          x="60" y="40">A</text>

    <text text-anchor="middle"
          x="60" y="75">A</text>

    <text text-anchor="end"
          x="60" y="110">A</text>

第一个 A,参考的是 (60,40) 的点,定义为start,那么参考点应该在字符的前面。

而剩下两个也是同样的道理:

tspan

现在,假如我们想在 text 里面添加一些特殊的字符效果,比如斜体,加粗等。由于,text 标签不能实现嵌套,所以,为了解决这个痛点,提出了 tspan 的标签。它其实就是一个可以嵌套的 text 标签。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<text x="10" y="30" style="font-size:12pt;">
  Switch among
  <tspan style="font-style:italic">italic</tspan>, normal,
  and <tspan style="font-weight:bold">bold</tspan> text.
</text>

tspan 里面同样可以自定义相关的自身属性。详细的可以参考 tspan 我这里就不详述了。

在 Path 展示 text

Text 一般可以横放,竖放。那有没有啥办法让文字可以按照一定的路径任意排放呢?

有的,这里可以使用textPath标签,来定义具体参考路径。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<path id="sharp-corner"
    d="M 30 110 100 110 100 160"
    style="stroke: gray; fill: none;"/>

<text>
    <textPath xlink:href="#sharp-corner">
    Making a quick turn
    </textPath>
</text>

如图:

具体细节我这里就不多说了。

Clip

在 DOM 中如果想展示一个图片的部分,或者以某种形状展示图片的部分,一般是通过一个 cover div 来实现的。不过,如果涉及到不规则图形的话,那么 DOM 就有天生缺陷了(当然使用 CSS 里的clip-path 可以完成,不过兼容性不太好)。而在 SVG 中,提供了clipPath 标签,能够让我们自定义裁剪图片的范围和形状。

clipPath 里面可以接任何图形,比如,path,rect 甚至是 text。使用的时候,直接在 style 中,指定 clip-path 即可,或者直接使用 clip-path属性指定。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<defs>
  <clipPath id="textClip">
    <text id="text1" x="20" y="20" transform="rotate(60)"
      style="font-family: 'Liberation Sans';
        font-size: 48pt; stroke: black; fill: none;">
CLIP
    </text>
  </clipPath>
 </defs>

 <use transform="translate(100, 0)"
  xlink:href="#shapes" style="clip-path: url(#textClip);"/>

   <use transform="translate(100, 0)"
  xlink:href="#shapes" clip-path="url(#textClip);"/>

或者说,如果我们想画一个圆的裁剪区域的话:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<defs>
     <clipPath id="circularPath" clipPathUnits="objectBoundingBox">
     <circle cx="0.5" cy="0.5" r="0.5"/>
    </clipPath>
</defs>

<use xlink:href="#shapes" style="clip-path: url(#circularPath);" />

Appendix 参考标签

g

分组标签应该毫无意外排第一,因为其实作为绘制图形中最常和最基本的标签。前面一篇文章也主要介绍过了,这里做点补充。

每一个分组标签都带有 id 属性,唯一标识该分组,为什么呢?

因为,后面我们可以使用该 id 标签添加动画,重用该分组等。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <g id="demo" stroke="green" fill="white" stroke-width="5">
     <circle cx="25" cy="25" r="15"/>
     <circle cx="40" cy="25" r="15"/>
     <circle cx="55" cy="25" r="15"/>
     <circle cx="70" cy="25" r="15"/>
   </g>

每个分组里面可以含有一些描述标签,比如 desc。 这些描述内容是不会被渲染的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<g id="demo" stroke="green" fill="white" stroke-width="5">
    <desc>Just Demo</desc>
     <circle cx="25" cy="25" r="15"/>
   </g>

use

该标签就是结合 g 标签一起使用,作用是可以复用 g 分组的样式。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<g id="Port">
      <circle style="fill: inherit;" r="10"/>
</g>
<use x="50" y="30" xlink:href="#Port" class="classA"/>

里面使用xlink:href 加上指定 group 的 id,然后通过xy属性指定副本放置的位置。不过,有一个限制,use 标签的 style 属性,并不能覆盖点原始的 group style 样式。而且,有时候,我们只是想使用一些模板,即,图形并未被解析,只有代码存在。这时候,就需要使用defs 来包裹了。

defs

用来保存一些代码,使其不会被浏览器解析。并且里面的分组可以被 use 属性的 style 样式所覆盖。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<defs>
    <g id="Port">
      <circle style="fill: inherit;" r="10"/>
    </g>
  </defs>

 <use x="50" y="50" xlink:href="#Port" style="fill: blue;"/>

symbol

该标签和g 标签类似,也是用来进行分组。不过,它有个特点,即,不会被浏览器所渲染。那它不和 defs 差不多吗?

恩,确实。不过,defs 是官方推荐,用来包裹一些模板 svg 代码而创造出来,用来增加可读性的标签。而 symbol 是存粹的作为一个模板。它可以独立于 svg 的 viewbox 来自定义子 viewbox 和 preserveAspectRatio。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <symbol id="sym01" viewBox="0 0 150 110">
  <circle cx="50" cy="50" r="40" stroke-width="8"
      stroke="red" fill="red"/>
  <circle cx="90" cy="60" r="40" stroke-width="8"
      stroke="green" fill="white"/>
</symbol>

<use href="#sym01"
     x="0" y="0" width="100" height="50"/>

同样使用该模板,也是使用 use 标签来完成。

image

既然use 可以重用 SVG 代码,那么 SVG 里面能不能重用已经画好的 png/jpg 的图片呢?

这时候,就需要用到image 标签。其可以用来加载外部的 PNG, JPEG 图片,注意,官方规定是前两种,其它图片支持不支持官方没做答复。即,如果你使用 GIF 图片,并不能保证所有的浏览器都能正常显示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<image xlink:href="kwanghwamun.jpg"
  x="72" y="92"
  width="160" height="120"/>
</svg>

同样,该 image 标签也具有自定义 preserveAspectRatio 的效果。

  • x: 定义水平位置
  • y: 定义垂直位置
  • width: 图片渲染的宽度,必须有。
  • height: 图片渲染的高度,必须有。
  • preserveAspectRatio: 控制图片的缩放

marker

marker 一般是用来画箭头或者线段始末的标识图形。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <defs>
    <marker id="Triangle" viewBox="0 0 10 10" refX="1" refY="5"
        markerWidth="6" markerHeight="6" orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>

  <polyline points="10,90 50,80 90,20" fill="none" stroke="black" 
      stroke-width="2" marker-end="url(#Triangle)" />

如图:

这里我们只需要里了解即可,因为在实际画的时候,直接使用相关工具生成更加方便。

a

这里的 a 标签和我们直接在 HTML 使用的超链接 a 标签类似。也是用来定义一个外链的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <a xlink:href="https://developer.mozilla.org/en-US/docs/SVG"
      target="_blank">
    <rect height="30" width="120" y="0" x="0" rx="15"/>
    <text fill="white" text-anchor="middle" 
          y="21" x="60">SVG on MDN</text>
  </a>

更多内容,可以关注我的公众号:前端小吉米。

分享吉米的前端路,后面也会定期推出当前热门的前端技术~ 比如,直播,VR 原文链接:http://www.ivweb.io/topic/59072cf006f26845b620dd87

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SVG 动画精髓
TL;DR 本文主要是讲解关于 SVG 的一些高级动画特效,比如 SVG 动画标签,图形渐变,路径动画,线条动画,SVG 裁剪等。 例如:路径动画 图形渐变: 线条动画: 以及,相关的动画的矩阵知识,
villainhr
2018/07/03
3.6K0
一个比想象中更骚气的圆-svg实现
之前写了一篇Canvas画图-一个比想象中更骚气的圆(渐变圆环),其实SVG也可以实现类似的效果,而且两者api惊人的相似。 关于SVG SVG是一种矢量图形,在图形改变尺寸的情况下质量不会损失。 相比canvas,svg有一个很大的优势就是内联进html的时候可以像操作dom一样操作svg,这样做起动画来非常方便。 本文不会介绍svg的基础知识,不过也没涉及什么复杂的东西,基于xml的语法还是比较好理解的。 期望实现的效果和Canvas一样是颜色非对称的沿着圆周进行渐变。 SVG的渐变 和之前讲ca
Bob.Chen
2018/05/02
3.4K0
一个比想象中更骚气的圆-svg实现
SVG快速入门小白篇
SVG .svg 使用xml语法 <?xml version='10.' standalone='no'> standalone 规定此SVG文件是否是独立的 或者是说含有外部文件的引用 在html中
起名字好难哟
2021/08/30
1.1K3
SVG快速入门小白篇
卡牌特效: svg不规则倒计时动效
导语:直播过程中,往往会有各种动画特效增强直播效果,近期需求中,设计要求在企鹅电竞PC官网上实现一种卡牌效果,在不规则图片上叠加倒计时效果。前端项目中,往往使用css来完成动画,像倒计时效果也可以使用css完成,但是相对来说css实现方案比较复杂,层次嵌套较多。倒计时动效要求覆盖图片的倒计时阴影为非规则且半透明的。在日常的圆环动画中,也会有类似的倒计时效果,只不过圆环是规则的,实现起来比较简单。但是基于圆环效果,再加上svg的mask特性,就可以实现此类特殊效果。 [ 实现动态图]  css的m
腾讯技术工程官方号
2019/07/17
2.3K0
卡牌特效: svg不规则倒计时动效
SVG 从入门到后悔,怎么不早点学起来(图解版)
可视化、机器学习等领域 JS 都有涉及到,而可视化方面已经被很多领域用到,比如大屏项目。
德育处主任
2022/09/08
3.5K0
线条之美,玩转SVG线条动画
通常来说web前端实现动画效果主要通过下面几种方案: 1. css动画: 利用css3的样式效果可以将dom元素做出动画的效果来。 2. canvas动画: 利用canvas提供的API,然后利用清除-渲染这样一帧一帧的做出动画效果。 3. svg动画: 同样svg也提供了不少的API来实现动画效果,并且兼容性也不差,本文主要讲解一下如何制作svg线条动画。
Javanx
2019/09/05
2.1K0
线条之美,玩转SVG线条动画
Web版Scada实现管道流水/电机转动最简单的方式
这段代码实现的功能是在SVG画布上绘制一条橙色的虚线,并且让这条虚线不断地重复移动。代码步骤解释:
科控物联
2024/04/12
5170
Web版Scada实现管道流水/电机转动最简单的方式
【教程】svg文字动画效果 - 路径加载+加粗渐显
一开始是直接手打出来的文本,然后通过 文字 → 创建轮廓 就可以创建出文字路径,但是没办法变成单一路径,只能围绕文字轮廓进行加载效果。
用户10984773
2025/07/03
680
【教程】svg文字动画效果 - 路径加载+加粗渐显
SVG 线条动画基础入门知识
1、CSS3 动画 2、javascript 动画(canvas) 3、html 动画(SVG)
Javanx
2019/09/04
3.1K0
SVG 线条动画基础入门知识
SVG学习笔记,持续记录。
SVG是一种用XML定义的语言,用来描述二维矢量及矢量/栅格图形。SVG提供了3种类型的图形对象:矢量图形(vectorgraphicshape,例如:由直线和曲线组成的路径)、图像(image)、文本(text)。图形对象还可进行分组、添加样式、变换、组合等操作,特征集包括嵌套变换(nestedtransformations)、剪切路径(clippingpaths)、alpha蒙板(alphamasks)、滤镜效果(filtereffects)、模板对象(templateobjects)和其它扩展(extensibility)。
房东的狗丶
2023/02/17
3.2K0
SVG学习笔记,持续记录。
【Web动画】SVG 线条动画入门
通常我们说的 Web 动画,包含了三大类。 CSS3 动画 javascript 动画(canvas) html 动画(SVG) 个人认为 3 种动画各有优劣,实际应用中根据掌握情况作出取舍,本文讨论
Sb_Coco
2018/05/28
2.5K0
【拓展】SVG实现环形进度条的原理
之前在项目中遇到一个环形进度条的需求,要求能实时更新进度,脑海中瞬间便蹦出css,svg,canvas3中方案,对于3种方案个人更偏向于svg,用法简单,代码量也很少,同时也便于实时控制。具体效果如下图:
pingan8787
2020/11/03
1.3K0
【拓展】SVG实现环形进度条的原理
三种 Loading 制作方案
Loading几乎是每个应用都会用到的一个组件。很多组件库都会提供相应的Loading组件,但是有的时候我们可能需要自定义Loading效果,掌握Loading组件制作的基础知识将变得非常必要。Loading主要就是一个旋转的圆环,而旋转部分则比较简单,直接通过CSS动画即可实现,所以关键部分就是得到Loading的圆环。
落落落洛克
2021/01/08
3.6K0
三种 Loading 制作方案
SVG 入门指南(初学者入门必备)
SVG,即可缩放矢量图形(Scalable Vector Graphics),是一种 XML 应用,可以以一种简洁、可移植的形式表示图形信息。目前,人们对 SVG 越来越感兴趣。大多数现代浏览器都能显示 SVG 图形,并且大多数矢量绘图软件都能导出 SVG 图形。SVG 主要可以概括为以下几点:
前端小智@大迁世界
2020/07/29
3.5K0
SVG 入门指南(初学者入门必备)
Power BI 模拟Apple Watch 环形图
左侧的环形图使用Power BI内置图表即可实现。中部的三个环形嵌套前期在讲小米的图表时涉及过(Power BI模拟小米运动APP三环效果),这里不再重复。右侧的环形图值得拿出来单独说明下,下方是Power BI实现效果。
wujunmin
2022/12/13
6620
Power BI 模拟Apple Watch 环形图
Power BI 内置图表实现Apple Watch环形图效果
去年此时看到Apple Wacth宣传图的一个环形图效果(下图右下角),并在Power BI使用第三方视觉对象实现。今年Power BI对SVG的支持大幅度提升,内置表格和新卡片图(不了解新卡片图参考此文:Power BI可视化的巅峰之作:新卡片图)都可以加载该图表。
wujunmin
2023/09/05
3490
Power BI 内置图表实现Apple Watch环形图效果
将 SVG 与媒体查询结合使用
在 HTML 文档中,我们可以根据视口的条件显示、隐藏或重新排列页面的某些部分。例如,如果浏览器窗口的宽度为 480 像素,我们可能会将导航从水平导航移动到垂直可折叠列表。将 SVG 与媒体查询一起使用时,我们可以做类似的事情。
玖柒的小窝
2021/09/12
7.2K0
将 SVG 与媒体查询结合使用
一步步教你用实现HTML5 SVG动画效果 [每日前端夜话(0x16)]
SVG是一种基于XML的,用于定义缩放矢量图形的标记语言。 它允许你通过在2D平面中确定的一组点来绘制路径、曲线和形状。 此外你还可以通过在这些路径上添加动态属性(例如笔触,颜色,粗细,填充等)来生成动画。
疯狂的技术宅
2019/03/27
2.6K0
一步步教你用实现HTML5 SVG动画效果 [每日前端夜话(0x16)]
SVG 路径动画简易指南
任何有开发经验的前端工程师都会考虑到不成体系的设备生态所带来的挑战。设备间不同的屏幕尺寸、分辨率和比例使得产品难以提供一致的体验,对于那些对产品有着像素级完美追求的人这种体验差异尤其显著! SVG(可缩放的矢量图形)完美地解决了上文中提到的部分问题。尽管 SVG 有它的局限性,但是在某些场景下是非常有用的,如果你有一个好的设计团队,你也可以基于SVG创建一些震撼的视觉体验,而不必担心给浏览器带来过重的渲染负担或阻碍页面的加载时间。
疯狂的技术宅
2019/03/27
3.9K0
SVG 路径动画简易指南
SVG
HTML体系中,最常用的绘制矢量图的技术是SVG和HTML5新增加的canvas元素。这两种技术都支持绘制矢量图和光栅图。不过canvas更偏重于动画的制作。所以,绘制矢量图的大任落到了SVG身上。
踏浪
2019/07/31
6.1K0
SVG
相关推荐
SVG 动画精髓
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档