SVG入门

一、概述

SVN 是一种图像格式.网页中可以使用的图片分为矢量图和位图,平时我们经常使用的jpg,png,gif图片是位图(基于像素点处理的),放大或缩小都会影响图片的清晰度,SVG图片是矢量图,全称是可缩放矢量图(Scalable Vector Graphics),如果你用记事本打开它,将会发现里面是一段可读的基于XML 语法的文本,这些文本就是对图像的描述,所以SVN图像本质上是文本文件,体积较小,且不管放大多少倍都不会失真。

上一个w3c上的例子看一看,下面是一个svg格式的图片用记事本打开后的文本内容(我格式化了一下)。

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>

可能你注意到了,代码里有个网址,这个网址是W3C的网址,意味着这段代码引用了W3C的外部的 SVG DTD(文档类型定义),在我们定义xhtml网页的时候也有类似的代码,有兴趣可以自行百度。

引入方式

既然SVG是图像,我们就可以和其他格式图片一样,将它引入网页,和进行base64的转码,这些内容在图片优化的章节讲过了。

1、用<img>、<object>、<embed>、<iframe>等标签的src属性引入到网页中。
<img src="book.svg">
<object id="object" data="book.svg" type="image/svg+xml"></object>
<embed id="embed" src="book.svg" type="image/svg+xml">
<iframe id="iframe" src="book.svg"></iframe>
2、CSS 也可以使用 SVG 文件。
.logo { background: url(icon.svg);  }  
3、同位图一样,SVG 文件也可以转为 BASE64编码,然后作为Data URI 写入网页。
<img src="data:image/svg+xml;base64,[data]">

上面的引入方式和位图是一样的,更美好的是HTML5 支持内联 SVG,能够将 SVG 元素直接嵌入 HTML 页面中。SVG元素作为DOM 的一部分,使前端彻底的获得了SVG图像的控制权。

4、 SVG 作为HTML5的一个新标签直接插入网页
<!DOCTYPE html>
<html>
<head></head>
<body>
<svg width="300" height="180">
    <circle id="mycircle" cx="400" cy="300" r="50" style="fill:red" />
</svg>
</body>
</html>

二、语法

SVG图像是二维图像,由点、线、面组成,SVG的语法依然很简单,无外乎就是点线面的结合,通过代码要绘制出复杂的图像绝非易事,视乎更需要我们拥有几何学的知识,好在现在有很多工具能够只做出很好的SVG图像。
在这里插入图片描述

<svg>标签

svg元素的width属性和height属性,实际上是定义了svg图像的视口(viewport),内部的图像如果超出视窗,将会被剪裁掉,这一点和PS是一样的,不同的是svg元素的视窗可以根据使用百分比,这样使SVG的视窗有了可伸缩性。

和所有的可视HTML元素一样,SVG图像的视口也是一个矩形,默认情况下矩形的左上顶点,是坐标的顶点(0,0),向右是横轴x轴,向下是纵轴y轴,通过横坐标和纵坐标,可以定位到svg元素的任何一点。

viewBox属性
通过定义<viewBox>属性的值,可以自定义图像的顶点和大小,有四个数字,分别是左上角的横坐标和纵坐标、视口的宽度和高度。如果定义了viewBox属性,相当于剪裁了图像,但视口的大小还是那么大,所以图像会放大去适配 SVG 视口的大小,相当于放大了图像。

SVG 内部元素

SVG 的内部元素有很多共似的属性,下面不再累述。

属性属性 值说明
含x属性数值如:x,x1,cx等,表示横坐标的值
含y属性数值如:y,y1,cy等,表示纵坐标的值
classclass属性用来指定对应的 CSS 类。
fill填充色
stroke描边色
stroke-width边框宽度

fill,stroke,stroke-width的属性值,也可以通过css定义。
绘制不同的形状,需要不同的属性,如矩形需要起点的坐标,宽度和高度,而正圆需要圆心的坐标和半径,线段需要起点和终点的坐标等等。

预定义的形状

SVG元素中可以使用一些预定义的形状元素,可被开发者使用和操作:
       1.矩形 <rect> 2.圆形<circle> 3.椭圆 <ellipse>4.线 <line>5.折线 <polyline>6.多边形 <polygon>7.路径 <path>

1、rect标签用于绘制矩形
<svg width="300" height="180">
 <rect x="0" y="0" height="100" width="200" style="fill: red" />
</svg>
2、circle绘制圆形
 <svg width="300" height="180">
      <circle cx="30"  cy="50" r="25" fill="blue" />
 </svg>

circle标签的cx、cy、r属性分别为横坐标、纵坐标和半径,单位为像素。

3、ellipse标签用于绘制椭圆。
<svg width="300" height="180">
    <ellipse cx="60" cy="60" ry="40" rx="20" />
</svg>

ellipse的cx属性和cy属性,指定了椭圆中心的横坐标和纵坐标(单位像素);
rx属性和ry属性,指定了椭圆横向轴和纵向轴的半径(单位像素)。

4、line绘制线段

line标签的x1属性和y1属性,表示线段起点的横坐标和纵坐标;x2属性和y2属性表示线段终点的横坐标和纵坐标

<svg width="300" height="180">
    <line x1="0" y1="0" x2="200" y2="0"  />
 </svg>
5、polyline标签用于绘制一根折线
<svg width="300" height="180">
      <polyline points="3,3 30,28 3,53" fill="none" stroke="black" />
</svg>

polyline标签的points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔。

6、polygon用于绘制多边形
<svg width="300" height="180">
     <polygon fill="green" stroke="orange" stroke-width="1" points="0,0 100,0 100,100 0,100 0,0"/>
</svg>

polygon的points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔。

7、path标签用于制路径。
<svg width="300" height="180">
    <path d="
          M 18,3
          L 46,3
          L 46,40
          L 61,40
          L 32,68
          L 3,40
          L 18,40
          Z
        "></path>
</svg>

path的d属性表示绘制顺序,它的值是一个长字符串,每个字母表示一个绘制动作,后面跟着坐标。

M:移动到(moveto)
L:画直线到(lineto)
Z:闭合路径

自定义的形状
1、defs标签用于自定义形状,它内部的代码不会显示,仅供引用。
<svg width="300" height="100">
    <defs>
        <g id="myCircle">
            <text x="25" y="20">圆形</text>
            <circle cx="50" cy="50" r="20"/>
        </g>
    </defs>
    <use href="#myCircle" x="0" y="0" />
    <use href="#myCircle" x="100" y="0" fill="blue" />
    <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>
pattern标签用于自定义一个形状,该形状可以被引用来平铺一个区域。
<svg width="500" height="500">
    <defs>
        <pattern id="dots" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse">
            <circle fill="#bee9e8" cx="50" cy="50" r="35" />
        </pattern>
    </defs>
    <rect x="0" y="0" width="100%" height="100%" fill="url(#dots)" />
</svg>

pattern标签将一个圆形定义为dots模式。patternUnits="userSpaceOnUse"表示pattern的宽度和长度是实际的像素值。然后,指定这个模式去填充下面的矩形。

text标签用于绘制文本
<svg width="100" height="100">
    <text x="10" y="10">Hello World</text>
</svg>

text的x属性和y属性,表示文本区块基线(baseline)起点的横坐标和纵坐标。文字的样式可以用class或style属性指定。

use标签用于复制一个形状。
<svg viewBox="0 0 30 10">
    <circle id="myCircle" cx="5" cy="5" r="4"/>
    <use href="#myCircle" x="10" y="0" fill="blue" />
    <use href="#myCircle" x="20" y="0" fill="white" stroke="blue" />
</svg>

use标签的href属性指定所要复制的节点,x属性和y属性是use标签左上角的坐标。另外,还可以指定width和height坐标。

g标签用于将多个形状组成一个组(group),方便复用。
<svg width="300" height="100">
    <g id="myCircle">
        <text x="25" y="20">圆形</text>
        <circle cx="50" cy="50" r="20"/>
    </g>
    <use href="#myCircle" x="100" y="0" fill="blue" />
    <use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>
image标签用于插入图片文件。
<svg viewBox="150 50 400 200" width="400" height="200">
    <image xlink:href="https://www.baidu.com/img/bd_logo1.png?where=super"
           width="50%" height="50%"/>
</svg>

xlink:href属性表示图像的来源。

animate标签用于产生动画效果。
<svg width="500px" height="120px">
    <rect x="0" y="10" width="100" height="100" fill="red">
        <animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
    </rect>
</svg>

animate的属性含义如下:
attributeName:发生动画效果的属性名。
from:单次动画的初始值。
to:单次动画的结束值。
dur:单次动画的持续时间。
repeatCount:动画的循环模式。

可以在多个属性上面定义动画。

<animate attributeName="x" from="0" to="500" dur="2s" repeatCount="indefinite" />
<animate attributeName="width" to="500" dur="2s" repeatCount="indefinite" />

animateTransform标签产生变形动画效果

<svg width="500px" height="500px">
    <rect x="250" y="250" width="50" height="50" fill="#4bc0c8">
        <animateTransform attributeName="transform" type="rotate" begin="0s" dur="10s" from="0 200 200" to="360 400 400" repeatCount="indefinite" />
    </rect>
</svg>

animateTransform的效果为旋转(rotate),这时from和to属性值有三个数字,第一个数字是角度值,第二个值和第三个值是旋转中心的坐标。from="0 200 200"表示开始时,角度为0,围绕(200, 200)开始旋转;to="360 400 400"表示结束时,角度为360,围绕(400, 400)旋转。

注意:animate标签对 CSS 的transform属性不起作用

三、JavaScript 操作

1、DOM 操作

如果 SVG 代码直接写在 HTML 网页之中,它就成为网页 DOM 的一部分,可以直接用 DOM 操作。

<svg
        id="mysvg"
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 800 600"
        preserveAspectRatio="xMidYMid meet"
>
    <circle id="mycircle" cx="400" cy="300" r="50" />
</svg>

上面代码插入网页之后,就可以用 CSS 定制样式。

circle {
	stroke-width: 5;
	stroke: #f00;
	fill: #ff0;
}
circle:hover {
	stroke: #090;
	fill: #fff;
}

然后,可以用 JavaScript 代码操作 SVG。

var mycircle = document.getElementById('mycircle');
mycircle.addEventListener('click', function(e) {
    console.log('circle clicked - enlarging');
    mycircle.setAttribute('r', 60);
}, false);        

上面代码指定,如果点击图形,就改写circle元素的r属性。

2、获取 SVG DOM

使用<object>、<iframe>、<embed>标签插入 SVG 文件,可以获取 SVG DOM。

var svgObject = document.getElementById('object').contentDocument;
var svgIframe = document.getElementById('iframe').contentDocument;
var svgEmbed = document.getElementById('embed').getSVGDocument();  

注意,如果使用<img>标签插入 SVG 文件,就无法获取 SVG DOM。

3、读取 SVG 源码

由于 SVG 文件就是一段 XML 文本,因此可以通过读取 XML 代码的方式,读取 SVG 源码。

<div id="svg-container">
    <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xml:space="preserve" width="500" height="440"
          >
            <!-- svg code -->
          </svg>
</div>

使用XMLSerializer实例的serializeToString()方法,获取 SVG 元素的代码。

var svgString = new XMLSerializer().serializeToString(document.querySelector('svg'));
4、SVG 图像转为 Canvas 图像

首先,需要新建一个Image对象,将 SVG 图像指定到该Image对象的src属性。

var img = new Image();
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var DOMURL = self.URL || self.webkitURL || self;
var url = DOMURL.createObjectURL(svg);
img.src = url;

然后,当图像加载完成后,再将它绘制到<canvas>元素。

img.onload = function () {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值