在网页上画一图形,比如星星或波浪线,开始是想着图形软件画一个的,后来发现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. 纯干货:Linux抓包命令集锦

    /******************************************************************************************* 版权声明* 本 ...

  2. Vue源码学习之双向绑定

    首发地址:CJWbiu's Blog 原理: ‘当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.definePr ...

  3. Zookeeper崩溃恢复过程(Leader选举)

    1. 崩溃恢复 a). leader选择过程可以保证新leader是ZXID最大的节点 b). ZAB协议确保丢弃那些只在leader上被提出的事务,场景 leader发出PROPOSAL收到ACK, ...

  4. matlab 基本操作

    导入excel 右键excel文件, import data, 选择column vector点击导入即可, 在右侧的workspace就可以看到添加的列变量了 在workspace中右键添加clas ...

  5. springboot集成freemarker 配置application.properties详解

    #配置freemarker详解 #spring.freemarker.allow-request-override=false # Set whether HttpServletRequest att ...

  6. Java中的while循环——通过示例学习Java编程(10)

    作者:CHAITANYA SINGH 来源:https://www.koofun.com/pro/kfpostsdetail?kfpostsid=20 在上一个教程中,我们讨论了for循环的用法.在本 ...

  7. iis6.0 建立站点

    公司网站的服务器甚多 其中还包括早期的iis6.0 的网站服务器 由于之前没有接触过 特此记录建立站点过程和注意事项 1.每个站点最好都新建一个用户名 方便管理 这里操作系统是 winXP 现在运行界 ...

  8. Nginx+Keepalived双主轮询负载均衡

    双主模式使用两个VIP,前段有2台服务器,互为主从,两台服务器同时工作,不存在资源浪费情况.同时在前端的DNS服务器对网站做多条A记录,实现了Nginx的负载均衡,当一台服务器故障时候,资源会转移到另 ...

  9. LeetCode Remove Duplicates from Sorted List 删除有序链表中的重复结点

    /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...

  10. js实现排序去重计算字符次数

    /*去重*/ var arr=[1,4,4,7,3,9,0,3,2,1,"你好","你","你好","你 "]; var ...