在网页上画一图形,比如星星或波浪线,开始是想着图形软件画一个的,后来发现SVG这绘图程序的语言,感觉甚是可以,就发了些时间学了一下,在此做一简单分享和记录。

菜鸟上是这么介绍的(SVG 是使用 XML 来描述二维图形和绘图程序的语言。SVG 指可伸缩矢量图形 (Scalable Vector Graphics),SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失,SVG 是万维网联盟的标准。。。。)

  而且SVG 文件可通过<embed>、<object> 或者 <iframe>标签嵌入 HTML 文档。也可以直接嵌入到HTML页面中,或您可以直接链接到SVG文件。反正使用起来还是挺方便的 ,只要浏览器支持,推荐浏览器能支持HTML5的使用。

  SVG确是很强大,能够绘制各种基本图形(矩形、圆、椭圆、多边形、曲线、路径、文本等),还有各种滤镜、模糊效果、阴影、渐变等特效。然后其中的路径path它不仅能创建其他基本形状,还能创建更多复杂形状(抛物线、波浪线.....甚至all)。反正path又是SVG里强大的一个,所以这里单独来讨论path。


  path中存在很多命令来定义路径形式和路径数据。可大致分为直线命令和曲线命令

直线命令

M = moveto

  字母“M”表示的是“Move to”命令,当解析器读到这个命令时,它就知道你是打算移动到某个点。跟在命令字母后面的,是你需要移动到的那个点的x和y轴坐标。比如移动到(10,10)这个点的命令,应该写成“M 10 10”。这一段字符结束后,解析器就会去读下一段命令。因为M命令仅仅是移动画笔,但不画线。所以M命令经常出现在路径的开始处,用来指明从何处开始画。比如:

<svg width="200px" height="200px" xmlns="http://www.w3.org/2000/svg">

  <path d="M10 10"/>

</svg>

这样是看不到任何图像的,因为这样只是把画笔移动到了x-10px,y-10px处。需要画出东西得在后面跟上其他画图命令如下面介绍到的命令。

注:每一个命令都有两种表示方式,一种是用大写字母,表示采用绝对定位。另一种是用小写字母,表示采用相对定位,(例如:从上一个点开始,向上移动10px,向左移动7px)path元素的形状是通过属性d定义的,因为属性d采用的是用户坐标系统,所以不需标明单位。

L = lineto

  字母“L”表示的是“line to”命令,L需要两个参数,分别是一个点的x轴和y轴坐标,L命令将会在当前位置和新位置(L前面画笔所在的点)之间画一条线段。这里就一起把“H”和“V”两个命令一起介绍了,

  • H = horizontal lineto ——绘制平行线。
  • V = vertical lineto ——绘制垂直线。

这两个命令都只带一个参数,标明在x轴或y轴移动到的位置,因为它们都只在坐标轴的一个方向上移动。比如,绘制平行线只需要确定x轴(H x),绘制垂直线只需确定y轴 ( V x )。

现在来整理以上命令绘制一个简单的矩形(当然SVG中有专门的 矩形命令<rect/>)。

<svg width="100px" height="100px" version="1.1" xmlns="http://www.w3.org/2000/svg">

  <path d="M10 10 H 100 V 100 H 10 L 10 10" stroke="black"/>

</svg>

上述路径是:画笔移动到(10,10)点,由此开始,向右移动90像素构成一条水平线,然后向下移动90像素,然后向左移动90像素,然后再向上移动100再回到起点。

Z = closepath

  “Z”命令为路径闭合命令,Z命令会从当前点画一条直线到路径的起点,尽管我们不总是需要闭合路径,但是它还是经常被放到路径的最后。另外,Z命令不用区分大小写。

然后实际上上面的例子我们可以优化为

<path d="M10 10 H 100 V 100 H 10 Z" stroke="black" fill="transparent"/>

  stroke:路径颜色,fill:闭合路径的填充颜色,stroke-width:路径宽度

曲线命令

  绘制平滑曲线的命令有三个,其中两个用来绘制贝塞尔曲线,最后一个用来绘制弧形或者说是圆的一部分(主要介绍C、S,A圆弧曲线这里将不予讨论)。

  • C = curveto
  • Q = quadratic Bézier curve
  • A = elliptical Arc

  C 和 Q 是用来绘制贝塞尔曲线的,“贝塞尔曲线”是什么?这东西老难解释了,在这实际上也用不着深入研究,如果有兴趣可以阅读这份Wikipedia的文档。贝塞尔曲线的类型有很多(线性贝塞尔曲线、二次方贝塞尔曲线、三次方贝塞尔曲线、四次方贝塞尔曲线、五次方贝塞尔曲线、……。),但是在path元素里,只存在两种贝塞尔曲线:三次贝塞尔曲线C,和二次贝塞尔曲线Q。

三次贝塞尔曲线C:

C x1 y1, x2 y2, x y 
<path d="M10 10 C 30 50, 100 60, 200 10" stroke="black" fill="transparent"/>

x1 y1, x2 y2 是两个控制点,x y 为曲线终点,这里盗一下图:

是不是很熟悉,在ps中绘制曲线的钢笔工具绘制的实际上就是“贝塞尔曲线”。

是不是多条三次贝塞尔曲线组合在一起可以得到一条很长的变化莫测的(^-<)平滑曲线,确实。但那是不是描点很麻烦,确实,所以 出现了S ( smooth curveto)命令,S命令可以用来创建与之前那些曲线一样的贝塞尔曲线,

但是,如果S命令跟在一个C命令或者另一个S命令的后面,它的第一个控制点,就会被假设成前一个控制点的对称点。如果S命令单独使用,前面没有C命令或者另一个S命令,

那么它的两个控制点就会被假设为同一个点,变成了二次贝塞尔曲线。

(MDN 贝塞尔曲线示意图)。

<path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"> ,M10 80 确定了画笔起点,C 后跟了两个控制点坐标,这时已经完成了一条三次贝塞尔曲线了,然后当我们需要再次绘制一条连接第一条曲线的

贝塞尔曲线时,跟上S命令后只需给出第二条三次贝塞尔曲线的第二个控制点的坐标即可(S指令会自动补出第一个控制点与第二个控制点对称 [蓝色部分]),于是就可以绘制出一条完美的平滑曲线了。

C指令有三个坐标参数,而S指令自动对称一个控制点,因此,跟在C指令之后的S指令,只需要2个参数,如下:

S x2 y2, x y

另一种可用的贝塞尔曲线是二次贝塞尔曲线Q,它比三次贝塞尔曲线简单,只需要确定一个控制点和一个终点即可(当然还有起点)。

<path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>

如下图:

A和C分别是起点和终点,B是控制点,其指令和参数为:

Q x1 y1, x y

同样,Q二次贝塞尔曲线也存在一简化连续绘制平滑曲线的命令,他就是T (smooth quadratic Bézier curveto)。

T会通过前一个控制点,推断出一个新的控制点。这意味着,在你的第一个控制点后面,可以只定义终点,就创建出一个相当复杂的曲线。需要注意的是,T命令前面必须是一个Q命令,

或者是另一个T命令,才能达到这种效果。如果T单独使用,那么控制点就会被认为和终点是同一个点,所以画出来的将是一条直线。继续上MDN示意图:

下面蓝色的控制点就是T命令自动补上的。

<path d="M10 80 Q 185 10, 360 80 T 720 80" stroke="black" fill="transparent"/>
<path d="M10 80 Q 95 10,185 80 T 360 80" stroke="black" fill="transparent"/>
<path d="M10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="transparent"/>

                        (效果图)

虽然二次贝塞尔曲线绘制比较三次贝塞尔曲线简单,但三次贝塞尔曲线拥有更大的自由度,具体使用哪种曲线,通常取决于需求,以及对曲线对称性的依赖程度。

最后附上一张绘制前的草图

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M10 80 Q 210 0 ,400 80 T 800 80 T 1200 80 T 1600 80" stroke="black" fill="transparent">
</svg>

画笔由原点向下移动了80px向左移动了10px,然后绘制了第一条二次贝塞尔曲线紧接着使用T指令绘制了第二条第三条第四条……,一条很长的波浪线就横空出世了。

SVG绘制的为矢量图,我感到最大的好处是可以动态的改变图形的形状和颜色,用来作动画真的太赞了(像我这种绘画艺术细菌为零的程序猿)。

参考文章:

深度掌握SVG路径path的贝塞尔曲线指令

路径

SVG path的更多相关文章

  1. 使用SVG Path绘图

    最近一个项目,需要做个Web版本的设计器,用来进行工厂流水线布局的设计. 项目中采用了SVG.JS来做,但是以前流水线是采用单纯的画线的方式实现.客户提出希望用不同的底纹表示不同的流水线,经过一番调查 ...

  2. SVG PATH 生成器

    参考网站:http://dayu.pw/svgcontrol/ 主要功能:手动可视化生成 SVG图片PATH路径. 效果如下: 代码如下: <!DOCTYPE html> <!-- ...

  3. svg path 动画效果

    http://www.zhangxinxu.com/wordpress/2014/04/animateion-line-drawing-svg-path-%E5%8A%A8%E7%94%BB-%E8% ...

  4. svg path 解析

    <pre><svg width="100%" height="100%" version="1.1" xmlns=&quo ...

  5. SVG path d Attribute

    Scalable Vector Graphics (SVG) 1.1 (Second Edition) W3C Recommendation 16 August 2011 http://www.w3. ...

  6. SVG Path高级教程

    课程分为四个方面: 1. Path概述 2. 移动和直线命令 3. 弧线命令 4. 贝塞尔曲线命令 Path概述 <path> 标签用来定义路径,Path字符串是由命令及其参数组组成的字符 ...

  7. Svg path画线(不管是直线还是曲线)在一定情况下线条的宽度不一的情况(记录)

    在项目中涉及到svg: 使用path划线实现图表功能. 记录在实现的过程中发现的问题:path在小像素的情况下画出的线条宽度不一样.这是为什么呢? 以下是我做的猜想: 可以看图 在宽度给的很足的时候没 ...

  8. svg path中的贝塞尔曲线

    首先介绍以下什么是贝塞尔曲线 贝塞尔曲线又叫贝茨曲线(Bezier),由两个端点以及若干个控制点组成,只有两个端点在曲线上,控制点不在曲线上,只是控制曲线的走向. 控制点个数为0时,它是一条直线; 控 ...

  9. svg path详解

    svg的<path>标签具有强大的功能,主要包括以下命令 M(move to) 参数:x,y L(line to) 参数:x,y H 参数:x V 参数:y C S Q T Z 参考:

随机推荐

  1. js获取文件MD5值

    原文链接:http://www.jianshu.com/p/940a9226fbbd   要在web页面中计算文件的md5值,还好这个项目是只需兼容现代浏览器的,不然要坑死了. 其实对文件进行md5, ...

  2. Spark-2.4.0源码:sparkContext

    在看sparkContext之前,先回顾一下Scala的语法.Scala构造函数分主构造和辅构造函数,辅构造函数是关键字def+this定义的,而类中不在方法体也不在辅构造函数中的代码就是主构造函数, ...

  3. 【Unity3D】Unity中用C#读取CSV文件

    1.创建csv文件 既然做实验嘛,没有资源怎么行,自己徒手写个csv文件吧,打开Numbers工具,新建一个表格文件,我的文件编辑截图如下: 创建完成后,导出成csv格式,我这里文件名为test.cs ...

  4. IoC和AOP使用扩展。。。

    实现依赖的多种方式. 1.理解构造注入. 2.掌握使用p命名空间实现属性注入. 3.理解不同的数据类型的注入方式. 4.如何通过构造注入为业务类注入所依赖的数据访问层对象,实现保存用户数据功能. 5. ...

  5. linux服务器安装nodejs运行环境

    安装nodejs运行环境 第一步:到node官网下载相应版本的安装包,将安装包放置服务器上,路径为 usr/local/node(可根据自身情况进行修改) 第二步:解压 ***.tar.xz格式文件需 ...

  6. 从零开始的全栈工程师——js篇2.15(offsetLeft)

    元素的属性 Div.attributes 是所有标签属性构成的数据集合 Div.classList 是所有class名构成的数组集合 在classList的原型链上看以看到add()和remove() ...

  7. 从零开始的全栈工程师——js篇2.9(this详解)

    this 一.this是js的一个关键字 指定一个对象然后去替代他    只研究函数内的this 分两种 函数内的this和函数外的this1)函数内的this指向行为发生的主体2)函数外的this都 ...

  8. 如何避开JavaScript浮点数计算精度问题(如0.1+0.2!==0.3)

    不知道大家在使用JS的过程中有没有发现某些浮点数运算的时候,得到的结果存在精度问题:比如0.1 + 0.2 = 0.30000000000000004以及7 * 0.8 = 5.60000000000 ...

  9. SpringEL和资源调用

    Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于JSP的EL表达式语言. Spring开发中经常涉及调用各种资源的情况,包含普通文件.网址.配置文件.系统环境变量等, ...

  10. Codeforces 802I Fake News (hard)

    Codeforces 802I 题意:统计所有不同子串出现次数的平方的和. 想法:建一个SAM,$Ans=\sum (step[i]-step[fa[i]])*right[i]^2$ #include ...