小试SVG之新手小白入门教程


Posted in Javascript onJanuary 08, 2019

基本概念

svg(Scalable Vector Graphics)是一种基于XML语法的图像格式,全称是可缩放矢量图,其它图像格式都是基于像素处理的,SVG则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真.SVG是面向图形,HTML时面向文本。

嵌入到HTML

SVG可以写在一个独立的文件中,然后用img, object, embed, iframe等标签插入网页

<img src="circle.svg">
<object id="object" data="circle.svg" type="image/svg+xml"></object>
<embed id="embed" src="icon.svg" type="image/svg+xml">
<iframe id="iframe" src="icon.svg"></iframe>

SVG文件可以转为base64编码,然后作为Data URI写入网页

<img src="data:image/svg+xml;base64,[data]" />

SVG书写的注意点

  • SVG的元素和属性必须按照标准格式来写,因为XML是确认大小写的
  • SVG里的属性值必须用引号引起来,就算是数值也必须这么做
  • SVG图像的默认大小是300像素(宽)x 150像素(高)
  • 后面的元素会渲染在前面元素之上

SVG的所有元素

SVG的所有元素

SVG的所有属性

SVG的所有属性

常用的形状元素

小试SVG之新手小白入门教程

其实上图只是对一些常用svg标签的初步认识,因为svg所提供的标签不止这些,而且比如path标签是在svg中最为通用的形状标签,因为它可以通过设置路径画出其它图形,比如矩形,圆,椭圆,多边形,多线段,甚至是复杂的贝塞尔曲线等等

path

第一次看到svg的标签的时候,打开控制台,也是一脸懵逼,首先这里面的d属性是个啥,M是啥,L是啥,Z是啥,H是啥,V是啥,C是啥,S是啥,Q是啥,T是啥,A是啥,我... 打扰了,打扰了

嗯,26个兄弟快凑齐了,马上就可以召唤神龙了。当然,path这条神龙在svg界就是“爸爸”,啥玩意都能给你弄出来,

想要通过path勾勒出美妙的图形,需要了解d这个属性,path标签中的d属性可以定义一系列的指令和参数,每一个指令通过一个字母来指定,比如上面说的M,它表示移动到,也就是"move to"的意思,比如让我们移动到(10, 10)的坐标点,就可以这样写:

<rect d="M10 10" />'

当然每一种字母都是区分大小写的,比如M是基于画布上的一个绝对坐标,而m则是基于上一个点的坐标,也就是相对坐标。比如有下面两种指令

<path d="M20,20 L40 40 M60 60 L80 80" fill="none" stroke="blue" stroke-width="5"/>

<path d="M20,20 L40 40 m60 60 L80 80" fill="none" stroke="blue" stroke-width="5"/>

小试SVG之新手小白入门教程

两个path唯一的区别就是第三个指令,一个是M60 60, 一个是m60 60

线段指令(Line commands)

  • L:L指令会拿到两个参数,x坐标和y坐标,然后从当前位置到指定参数坐标位置来绘制线段
  • H:H其实是horizontal的缩写,意为绘制出水平方向的线段,因为方向已确定,所以只需一个参数就能完成线段的绘制
  • V:同H同理,只不过表示垂直方向(vertical)的线段绘制

比如用H和V来绘制一个矩形, 我们一步一步来

step1

<path d="M10 10 H 90" fill="none" stroke="blue"/>

小试SVG之新手小白入门教程

step2

<path d="M10 10 H 90 V 90" fill="none" stroke="blue"/>

小试SVG之新手小白入门教程

step3

<path d="M10 10 H 90 V 90 H 10" fill="none" stroke="blue"/>

小试SVG之新手小白入门教程

step4

<path d="M10 10 H 90 V 90 H 10 V 10" fill="none" stroke="blue"/>

小试SVG之新手小白入门教程

上面的写法也可以通过一个指令来简写一下,这就用到了Z指令

Z:该指令的作用是从当前位置向起始点画出一条线段,它一般都被放置在一连串节点的末尾,并且不区分大小写。可以理解为”闭环“指令

所以上例可以写成这样,也能达到同样的效果

<path d="M10 10 H 90 V 90 H 10 Z" fill="none" stroke="blue"/>

同样,上例也可以通过相对定位的形式进行改写,效果是一致的

<path d="M10 10 h 80 v 80 h -80 Z" fill="transparent" stroke="blue"/>

小试SVG之新手小白入门教程

曲线指令(Curve commands)

一说到曲线,那贝塞尔曲线是绕不开的,对于曾高数挂科的我来说是很排斥的,但好在闲着蛋疼,遂学之。

path标签中有两类贝塞尔曲线,一种叫做“三次贝塞尔曲线(cubic curve)“, 一种叫做”二次贝塞尔曲线(quadratic curve)“,这名字听起来就不接地气。

那先从三次贝塞尔曲线说起

C:该指令用于创建一个三次贝塞尔曲线,需指定三组参数

比如:

<path d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>

首先,(20 20)和(40 20)表示控制节点,一个是描述曲线起始点的斜率,另一个是描述曲线终止点的斜率,最后一组(50 10)表示曲线的终点。总结一下这段示例,就是有一条从(10 10)到(50 10)的一条线段,通过设置两个控制点的斜率,使这条线段的各个点弯曲成正确的(符合斜率趋势的)曲线。

MDN上有多组曲线的对比示例。

小试SVG之新手小白入门教程

这里面我们再添加一种情况,就是设置两个水平的控制节点,来看看线段是如何变化的

<path d="M10 10 C 10 10, 40 10, 50 10" stroke="black" fill="transparent"/>

小试SVG之新手小白入门教程

通过S指令能生成和上述示例中同样的平滑曲线,使用S指令分为以下两种情况

  • S指令跟在C或者另一个S指令之后:那S指令的开始控制节点就是基于前一个控制节点的对称点,并且S指令指定的第一组节点是结束控制节点
  • 单独的S指令:两个控制节点会被设置为同一个点

比如如下代码

<svg
  xmlns="http://www.w3.org/2000/svg"
  width="190"
  height="160"
 >
  <path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>

  <circle cx="10" cy="80" r="2" fill="red"/>
  <circle cx="95" cy="80" r="2" fill="red"/>
  <circle cx="180" cy="80" r="2" fill="red"/>
  <circle cx="150" cy="150" r="2" fill="red"/>
 </svg>

我们通过不断改变S的第一组节点来看图形的变化趋势

小试SVG之新手小白入门教程

我们可以看到,随着不断给S指令结束控制节点的横坐标累加,曲线会向右偏移。

接下来看下S指令前面没有其他C或者S指令的情况,代码如下

<svg
xmlns="http://www.w3.org/2000/svg"
width="300"
height="300"
>
<path d="M10 80 S 95 150, 180 80" stroke="black" fill="transparent"/>

<circle cx="10" cy="80" r="2" fill="red"/>
<circle cx="95" cy="150" r="2" fill="red"/>
</svg>

小试SVG之新手小白入门教程

另一种曲线是二次贝塞尔曲线(quadratic curve)

它通过指令Q来来进行描述,相较于三次贝塞尔曲线,它更为简单。

Q:只需要指定两组参数,第一组表示控制节点的坐标,第二组表示终点坐标。

示例:

<svg
xmlns="http://www.w3.org/2000/svg"
width="300"
height="300"
>
<path d="M10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>

<circle cx="10" cy="80" r="2" fill="red"/>
<circle cx="95" cy="20" r="2" fill="red"/>
<circle cx="180" cy="80" r="2" fill="red"/>
</svg>

小试SVG之新手小白入门教程

和三次贝塞尔类似,二次贝塞尔也提供了快捷的玩法,那就是T指令

T:通过找到前一个控制节点,来推断出一个新的控制点,T指令后面只需要指定一组结束点坐标即可,由于T指令是基于前一个控制点的基础上来生成的,所以T指令之前必须要有Q指令或者其他T指令,否则生成的控制节点就和前一个控制节点就会重合,在画布上看到的就仅仅是一条直线。

示例:

<svg
  xmlns="http://www.w3.org/2000/svg"
  width="300"
  height="300"
 >
  <path d="M10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="transparent"/>

  <circle cx="10" cy="80" r="2" fill="red"/>
  <circle cx="52.5" cy="10" r="2" fill="red"/>
  <circle cx="95" cy="80" r="2" fill="red"/>
  <circle cx="180" cy="80" r="2" fill="red"/>

 </svg>

小试SVG之新手小白入门教程

在上面几个例子中,两种曲线都生成了同样的结果,虽然三次贝塞尔允许更多的自由度,但是决定使用哪种曲线还要依照具体情形以及对称曲线的数量来定

弧度(Arcs)

在svg中也可以创建弧度这种曲线,它通过A指令来指定,A指令可以接收7个参数

  • rx:x轴半径
  • ry:y轴半径
  • x-axis-rotation:弧形的旋转角度
  • large-arc-flag:决定弧线是大于180度好事小于180度,0表示小角度弧,1表示大角度弧
  • sweep-flag:表示弧线的方向,0表示从起点到终点沿逆时针画弧,1表示从起点到终点沿顺时针画弧
  • x:弧形终点的横坐标
  • y:弧形终点的纵坐标

示例:

<?xml version="1.0" standalone="no"?>
 <svg width="325px" height="325px" version="1.1" xmlns="http://www.w3.org/2000/svg">
 <path d="M80 80
   A 45 45, 0, 0, 0, 125 125
   L 125 80 Z" fill="green"/>
 <path d="M230 80
   A 45 45, 0, 1, 0, 275 125
   L 275 80 Z" fill="red"/>
 <path d="M80 230
   A 45 45, 0, 0, 1, 125 275
   L 125 230 Z" fill="purple"/>
 <path d="M230 230
   A 45 45, 0, 1, 1, 275 275
   L 275 230 Z" fill="blue"/>
 </svg>

小试SVG之新手小白入门教程

饼图

通过学习path,我们来绘制一个简单的饼图

<svg width="325" height="325" xmlns="http://www.w3.org/2000/svg">
  <path d="M80 80
    A 45 45, 0, 0, 0, 125 125
    L 125 80 Z" fill="green"/>
  <path d="M170 80
    A 45 45, 0, 0, 1, 125 125
    L 125 80 Z" fill="red"/>
  <path d="M170 80
    A 45 45, 0, 0, 0, 125 35 
    L 125 80 Z" fill="blue" />
  <path d="M80 80
    A 45 45, 0, 0, 1, 125 35
    L 125 80 Z" fill="pink"/>
 </svg>

小试SVG之新手小白入门教程

小结

在最近的一些项目中,接触到了部分有关svg的需求,所以这篇文章就是记录下自己在学习svg的一部分总结,比较基础,方便自己今后的复习和查阅。

参考资源

MDN SVG

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
JS event使用方法详解
Apr 28 Javascript
javascript 获取url参数和script标签中获取url参数函数代码
Jan 22 Javascript
JavaScript中json对象和string对象之间相互转化
Dec 26 Javascript
关于extjs4如何获取grid修改后的数据的问题
Aug 07 Javascript
javascript学习笔记(八)正则表达式
Oct 08 Javascript
javascript正则表达式之search()用法实例
Jan 19 Javascript
jQuery插件Validate实现自定义表单验证
Jan 18 Javascript
微信小程序 视图层(xx.xml)和逻辑层(xx.js)详细介绍
Oct 13 Javascript
Node.js搭建WEB服务器的示例代码
Aug 15 Javascript
详解基于Vue,Nginx的前后端不分离部署教程
Dec 04 Javascript
vue element upload组件 file-list的动态绑定实现
Oct 11 Javascript
Vue3新特性之在Composition API中使用CSS Modules
Jul 13 Javascript
vue组件通信传值操作示例
Jan 08 #Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
Jan 08 #Javascript
vuejs简单验证码功能完整示例
Jan 08 #Javascript
详解React中合并单元格的正确写法
Jan 08 #Javascript
JS简单判断是否在微信浏览器打开的方法示例
Jan 08 #Javascript
JQuery搜索框自动补全(模糊匹配)功能实现示例
Jan 08 #jQuery
Angular6 发送手机验证码按钮倒计时效果实现方法
Jan 08 #Javascript
You might like
PHP验证码函数代码(简单实用)
2013/09/29 PHP
PH P5.2至5.5、5.6的新增功能详解
2014/07/14 PHP
PHP yii实现model添加默认值的方法(两种方法)
2016/11/10 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
JXTree对象,读取外部xml文件数据,生成树的函数
2007/04/02 Javascript
js url传值中文乱码之解决之道
2009/11/20 Javascript
javascript parseInt与Number函数的区别
2010/01/21 Javascript
JavaScript/jQuery 表单美化插件小结
2012/02/14 Javascript
js加载之使用DOM方法动态加载Javascript文件
2013/11/08 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
JavaScript实现两个Table固定表头根据页面大小自行调整
2014/01/03 Javascript
jquery map方法使用示例
2014/04/23 Javascript
深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解
2015/03/05 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
js模拟微博发布消息
2017/02/23 Javascript
原生JS实现圆环拖拽效果
2017/04/07 Javascript
JS图片预加载插件详解
2017/06/21 Javascript
layui动态表头的实现代码
2019/08/22 Javascript
JS 遍历 json 和 JQuery 遍历json操作完整示例
2019/11/11 jQuery
jQuery实现移动端下拉展现新的内容回弹动画
2020/06/24 jQuery
vue实现页面切换滑动效果
2020/06/29 Javascript
vue-video-player 断点续播的实现
2021/02/01 Vue.js
[48:12]Secret vs Optic Supermajor 胜者组 BO3 第三场 6.4
2018/06/05 DOTA
Python代理抓取并验证使用多线程实现
2013/05/03 Python
Python下的subprocess模块的入门指引
2015/04/16 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
通过案例解析python鸭子类型相关原理
2020/10/10 Python
Agoda.com官方网站:便宜预订全球酒店,高达80%的折扣
2018/04/04 全球购物
机械制造专业个人的自我评价
2013/12/28 职场文书
化妆品促销方案
2014/02/24 职场文书
2014党员学习兰辉先进事迹思想汇报
2014/09/17 职场文书
乡镇干部个人整改措施思想汇报
2014/10/10 职场文书
会计主管竞聘书
2015/09/15 职场文书
运动会主持人开幕词
2016/03/04 职场文书
2016年第16个全民国防教育日宣传活动总结
2016/04/05 职场文书
vue-router中hash模式与history模式的区别
2021/06/23 Vue.js