初窥 SVG Path 动画

本文讨论的主题是 SVG Path 动画(路径动画)。之所以要讨论这个话题,是因为在项目中有要求用到它。所谓 SVG Path 动画,就是让图形有像人实时绘制一样的动画效果,就比如下面这种:

1. 基础知识

开始 SVG Path 动画之前,你需要先准备一些基础知识,主要是SVG是什么,以及 Path(路径) 和 Stroke (描边)这两个东东。

1.1 SVG

SVG 指可伸缩矢量图形 (Scalable Vector Graphics),因此,SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失。SVG 除了制作图像之外,还有各种用途,比如动画、 ICONFONT等。

看看兼容性:

1.2 path(路径)

path 元素是 SVG 基本形状中最强大的一个,它不仅能创建其他基本形状,还能创建更多其他形状。另外,path 只需要设定很少的点,就可以创建平滑流畅的线条(比如曲线)。

<svg>
 <path d="M100 100, A120 120, -45 0 1, 300 300 A120 120, -45 0 1, 100 100"
  stroke="#05D380" stroke-width="2"
  fill="none"/>
</svg>

1.3 stroke(描边)

要实现绘制动画效果,除了 path 外,还要依靠 stroke 的两个重要属性来完成,即 stroke-dasharraystroke-dashoffset

  • 属性 stroke-dasharray:该值可能由两个值合写,使用英文逗号(,)分隔,第一个值是画出的每段实线线段的长度,第二个值是各段之间空隙的长度。如果无分隔,则说明两个值都是一样大小的。
  • 属性 stroke-dashoffset:指定每个实线线段的起始偏移量。正数从路径起始点向前偏移,负数则向后。

举例而言,如果要实现类似 CSS 中 border-style: dotted; 这样的虚线效果,则可以设置 stroke-dasharray:5,10,第一个数字表示每一段实线长度为 5,第二个表示实线直接间隔长度为 10

<svg>
 <path d="M100 100, A120 120, -45 0 1, 300 300 A120 120, -45 0 1, 100 100"
  stroke="#05D380" stroke-width="2"
  fill="none"
  stroke-dasharray="5,10"/>
</svg>

1.4 CSS 控制

我们将 SVG 代码插入到 HTML 文件中,SVG本身也是一种DOM节点,能使用CSS属性控制。例如上例也可以改成这样。我们为 path 定义了一个样式类 mypath,并在 <style> 中进行定义:

<style>
.mypath {
    stroke: #05D380;
    stroke-width: 2;
    stroke-dasharray: 5, 10;
    fill: none;
}
</style>

<svg>
    <path d="M100 100, A120 120, -45 0 1, 300 300 A120 120, -45 0 1, 100 100" class="mypath" />
</svg>

1.5 CSS3 的 keyframes 和 animation

要动画,就需要借助 CSS3 的 keyframesanimation。此处知识略。

2. SVG Path 绘制动画原理分析

假设一条路径的总长度为 888,我们设置这条路径的 storke-dasharray:888 ,于是这条路径就变成了由长度 888 的实线与长度 888 的间隔组成;但是,由于路径的总长度只有 888,因此看上去和正常场景是一样的,只不过在实线的后面,还跟着一段长度 888 的间隔;

当我们设置 stroke-dashoffset:100 , 我们将该虚线向前偏移了 100;那我们设置 stroke-dashoffset:888,该路径就变成了空白。

在 CSS 中,你如果设置一个块级元素 margin-left: -100%,很可能你在屏幕中就看不到它了。其实 stroke-dashoffset 的表现也和这个差不多,用于定义“偏移”。

通过控制 stroke-dashoffset 属性值,我们就控制了这个路径的展示和隐藏,再配合 CSS3 的 animation 动画,就能够完美的实现绘制动画。

3. SVG Path 绘制动画实践

3.1 获得路径长度

路径的长度可以使用 js 来获得,上例的路径长度就是 888

var path = document.querySelector('.mypath');
var length = path.getTotalLength(); // 888.7

3.2 设置stroke-dasharray和stroke-dashoffset

我们设置 stroke-dasharraystroke-dashoffset 的值都为 888,这个值恰好是路径的长度。

不同的 path 其长度是不一样的,请先用 js 获取其长度。

<style>
.mypath {
    stroke: #05D380;
    stroke-width: 2;
    stroke-dasharray: 888;
    stroke-dashoffset: 888;
    fill: none;
}
</style>

<svg>
    <path d="M100 100, A120 120, -45 0 1, 300 300 A120 120, -45 0 1, 100 100" class="mypath" />
</svg>

你会发现什么都看不到,但当你手动修改 stroke-dashoffset 的值,使之从 888 逐步减少到 0时,你会发现图像会慢慢出现。

3.3 配合 CSS3 animation 动画

接下来,使用 CSS3 动画中的 keyframe 来控制 stroke-offset属性,把它的值从 888 变为 0,Path 绘制效果就出来了。

<style>
.mypath {
    stroke: #05D380;
    stroke-width: 2;
    stroke-dasharray: 888;
    stroke-dashoffset: 888;
    fill: none;
    -webkit-animation: go 4s ease-in-out forwards;
}

@-webkit-keyframes go {
    0% {
        stroke-dashoffset: 888;
    }
    100% {
        stroke-dashoffset: 0;
    }
}
</style>
<svg>
    <path d="M100 100, A120 120, -45 0 1, 300 300 A120 120, -45 0 1, 100 100" class="mypath" />
</svg>

到这里,SVG Path 绘制动画基本就讲完了,仅限于入门使用。你可以找其他的 path 来试试看。

路径动画的方向,其实是路径本身就规定了的,所以如果你需要一个特别的路径动画,那么就得保证路径是按你动画要求的步骤来绘制的。

4. 如果获得 path?

这是补充的内容。一开始我看到 path 元素里的 d 值,我是崩溃的,这玩意是啥啊。我怎么才能得到这个值呢?

首先,你得有一个 SVG 文件,怎么制作 SVG 文件,这个自己 Google 吧。

获得 SVG 文件之后,使用文本编辑器打开它,你会看到里面有你所需要的 svg 标签,也有你需要的 path 元素了,你所需要做的,可能就是拷贝,然后适当修改一下,最后再加上动画即可。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.4K7
来自专栏跟着阿笨一起玩NET

c#实现打印功能

3562
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2997
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2955
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4355
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

27110
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5657
来自专栏闻道于事

js登录滑动验证,不滑动无法登陆

js的判断这里是根据滑块的位置进行判断,应该是用一个flag判断 <%@ page language="java" contentType="text/html...

8338
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4214
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2810

扫码关注云+社区