使用XML描述的矢量文件
W3C标准(1.1):
http://www.w3.org/TR/SVG11/
浏览器支持情况:
http://caniuse.com/#cats=SVG
目录
[1]
[TOC]
一、SVG基本概念
1.1SVG的使用方式
1.1.1 浏览器直接打开
1.1.2 在HTML中使用<img>标签使用
<img src="images/icon.svg" width="50" height="50">
1.1.3 直接在HTML中使用SVG标签
1.1.4 作为CSS背景
.container{
background: white url(bg.svg) repeat;
1.2 基本图形和属性
<circle>
<ellipse>
<polyline>
<polygon>
stroke
stroke-width
transform
<line x1="start-x" y1="start-y" x2="end-x" y2="end-y"/>
直线:起点(start-x,start-y),终点(end-x,end-y)
<rect x="left-x" y="top-y" width="width" height="height"/>
矩形:左上角(left-x,top-y),宽高width,height
<circle cx="center-x" cy="center-y" r="radius"/>
圆: 圆心(center-x, center-y) 半径 r
<ellipse cx="center-x" cy="center-y" rx="x-radius" ry="y-radius"/>
椭圆: 圆心(center-x, center-y) xy轴半径 rx, ry
<polygon points="points-list"/>
多边形: 由一系列坐标组成, points-list: x1 y1 x2 y2 x3 y3 ....
<polyline points="points-list"/>
折线: 由一系列坐标组成, points-list: x1 y1 x2 y2 x3 y3 ....
rx\ry表示圆角度数,如果只给一个值,另一个也会用到同一个值。
1.2.2 <circle>
1.2.8 实例
<svg xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" rx="5" ry="5" width="150" height="100" stroke="red" fill="none"></rect>
<circle cx="250" cy="60" r="50" stroke="red" fill="none"></circle>
<ellipse cx="400" cy="60" rx="70" ry="50" stroke="red" fill="none"></ellipse>
<line x1="10" y1="120" x2="160" y2="220" stroke="red"></line>
<polyline points="250 120 300 220 200 220" stroke="red" fill="none"></polyline>
<polygon points="250 120 300 220 200 220" stroke="red" stroke-width="5" fill="yellow" transform="translate(150 0)"></polygon>
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 500" preserveAspectRatio="xMidYMax meet">
<!--Face-->
<circle cx="100" cy="100" r="90" fill="#39F"></circle>
<!--Eyes-->
<circle cx="70" cy="80" r="20" fill="white"></circle>
<circle cx="130" cy="80" r="20" fill="white"></circle>
<circle cx="65" cy="75" r="10" fill="black"></circle>
<circle cx="125" cy="75" r="10" fill="black"></circle>
<!--Smile-->
<path d="M 50 140 A 60 60 0 0 0 150 140" stroke="white" stroke-width="3" fill="none"></path>
<rect id="viewBoxIndicator" stroke="red" stroke-width="3.5" fill="none" x="0" y="0" width="600" height="500"></rect>
<svg xmlns="...">
<g stroke="green" fill="none">
<rect x="100" y="50" width="100" height="50"></rect>
<rect x="140" y="100" width="20" height="120"></rect>
实例:查看原代码
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="600" viewBox="-200.5 -100.5 1000 600">
<g id="coord">
<line x1="0" y1="0" x2="300" y2="0"></line>
<line x1="0" y1="0" x2="0" y2="300"></line>
<circle cx="0" cy="0" r="2"></circle>
<circle cx="100" cy="0" r="2"></circle>
<circle cx="200" cy="0" r="2"></circle>
<circle cx="300" cy="0" r="2"></circle>
<circle cx="0" cy="200" r="2"></circle>
<circle cx="0" cy="100" r="2"></circle>
<circle cx="0" cy="300" r="2"></circle>
</defs>
<text fill="black" x="-55" y="5">Group</text>
<use xlink:href="#coord" stroke="black" fill="black"></use>
<g id="a" stroke="red" fill="red" transform="translate(50, 50)">
<text x="5" y="20">a</text>
<use xlink:href="#coord"></use>
<g id="b" stroke="blue" fill="blue" transform="translate(50, 50)">
<text x="5" y="20">b</text>
<use xlink:href="#coord"></use>
<g id="c" stroke="green" fill="green" transform="translate(50, 50) rotate(30)">
<text x="5" y="20">c</text>
<use xlink:href="#coord"></use>
<g id="d" stroke="orange" fill="orange" transform="translate(150, 150)">
<text x="5" y="20">d</text>
<use xlink:href="#coord"></use>
<svg xmlns="http://www.w3.org/2000/svg">
<linearGradient id="grad1" x1="0" y1="0" x2="1" y2="1"> <--可以添加gradientUnits的属性来改变坐标-->
<stop offest="0" stop-color="#1497fc" />
<stop offest="0.5" stop-color="#a469be" />
<stop offest="1" stop-color="#ff8c00" />
</linerGradient>
</defs>
<rect x="100" y="100" fill="url(#grad1)" width="200" height="150" />
<svg xmlns="http://www.w3.org/2000/svg">
<radialGradient id="grad2" cx="0.5" cy="0.5" r="0.5" fx="0.6" fy="0.3"> <--fx和fy表示偏移-->
<stop offest="0" stop-color="rgb(20,151,252)" />
<stop offest="0.5" stop-color="rgb(164,105,190)" />
<stop offest="1" stop-color="rgb(255,140,0)" />
</radialGradient>
</defs>
<rect x="100" y="100" fill="url(#grad2)" width="200" height="150" />
patternUnits:
objectBoundingBox : (默认)为容器百分比
userSpaceOnUse : width 和 height 以世界坐标系为准,为宽度、高度
patternContentUnits:
userSpaceOnUse : (默认)为以世界坐标系为准
objectBoundingBox : pattern 的子元素(这里指 circle 和 polygon,尺寸属性为 rect 的百分比)
一般情况下 patternContentUnits 为 objectBoundingBox 时,patternUnits 也为 objectBoundingBox,好处理
<svg xmlns="http://www.w3.org/2000/svg">
<pattern id="p1" x="0" y="0" width="0.2" height="0.2" >
<circle cx="10" cy="10" r="5" fill="red"></circle>
<polygon points="30 10 60 50 0 50" fill="green"></polygon>
</pattern>
</defs>
<rect x="100" y="100" width="400" height="300" fill="url(#p1)" stroke="blue"></rect>
他还有个patternContentUnits="objectBoundingBox/userSpaceOnUse"属性:
<pattern id="p1" x="0" y="0" width="0.2" height="0.2" patternUnits="objectBoundingBox" patternContentUnits="objectBoundingBox">
四、Path高级教程
4.1 Path概述
强大的绘图工具
规范:https://www.w3.org/TR/SVG/paths.html
由命令及其参数组成的字符串,如:
<path d="M0,0L10,20C30-10,40,20,100,100" stroke="red">
<tiger.svg>
<path d="M0,0L10,20C30-10,40,20,100,100" stroke="red">
<path d="M 0 0 L 10 20 C 30 -10 40 20 100 100" stroke="red">
<path d="M 0 0,L 10 20,C 30 -10 40 20 100 100" stroke="red">
path命令汇总
凡是出现大写字母表示后续坐标为绝对坐标, 凡是小写字母都代表相对于上一个坐标的相对位移。 Z 同 z 无差别,因为表示闭合,其后不用跟坐标。
C/c (cx1 cy1 cx2 cy2 x y)+
从当前点画一条到(x, y)的三次贝塞尔曲线, 曲线的开始控制点和终点控制点为别为 (cx1, cy1), (cx2, cy2).
S/s (cx2 cy2 x y)+
此命令只能跟在 C 命令后使用, 假设 C 命令生成曲线 s, S 命令的作用是再画一条到 (x, y)的三次贝塞尔曲线, 曲线的终点控制点是 (cx2, cy2), 曲线的开始控制点是 s 的终点控制点关于 s 终点的对称点.
Q/q (cx,cy,x,y)+
从当前点画一条到(x, y)的二次贝塞尔曲线, 曲线的控制点为(cx, cy)
T/t (x,y)+
此命令只能跟在 Q 命令后使用, 假设 Q 命令生成曲线 s, T 命令的作用是从 s 的终点再画一条到(x y)的二次贝塞尔曲线, 曲线的控制点为 s 控制点关于 s 终点的对称点. T 命令生成的曲线会非常平滑
A(a) rx ry x-axis-rotation large-arc sweep x y
画一段到(x,y)的椭圆弧. 椭圆弧的 x, y 轴半径分别为 rx,ry. 椭圆相对于 x 轴旋转 x-axis-rotation 度. large-arc=0表明弧线小于180读, large-arc=1表示弧线大于180度. sweep=0表明弧线逆时针旋转, sweep=1表明弧线顺时间旋转. 具体解释看如何绘制椭圆弧
ry - (radius-y)弧线所在椭圆的Y半轴长
xr - (xAxis-rotation)弧线所在椭圆的长轴角度,那么 x-axis-rotation 又是什么意思呢? b, c, d, e 产生的前提是 椭圆的 x 轴与用户坐标系的 x 轴是平行的.
F 图表示椭圆 x 轴相对于用户坐标系的 x 轴旋转30度所产生的椭圆弧. 灰色的部分表示原来产生的椭圆弧.
laf - (large-arc-flag)是否选择弧长较长的那一段
sf - (sweep-flag)是否选择逆时针方向的那一段弧
x,y - 弧的终点位置
<svg xmlns="http://www.w3.org/2000/svg">
<pattern id="grid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<path stroke="#f0f0f0" fill="none" d="M0,0H20V20"></path>
</pattern>
</defs>
<rect width= "100%" height="100%" fill="url(#grid)"></rect>
<text x="100" y="100" dx="20 40 60 80 100" dy="20 20 20 20 20" style="font-size: 50px">ABCDE</text> //dx让文字前间距偏移;dy让文字上间距偏移
<path d="M 0 100 H 200 M 100 0 H 200" transform="translate(0, 60)" stroke="red"> </path> //辅助线
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Examples</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
</head>
<!-- pattern 笔刷 -->
<svg xmlns="http;//www.w3.org/2000/svg" width="100%" height="1000">
<defs> <pattern id="grid" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<path stroke="#F0F0F0" fill="none" d="M 0 0,H 20,V 20"></path>
</pattern> </defs>
<rect width="100%" height="1000" fill="url(#grid)"></rect>
<text id="sintext" x='100' y='160' style="font-size:16px;font-family:'Arial';"></text>
<path d="M 100 0,V 200,M 0 100,H 800" transform="translate(0,60)" stroke="red"></path>
<script type="text/javascript">
var text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var n = text.length;
var x = [];
var i = n;
var y = null;
var s = 100,w = 0.02,t = 0;
while(i--){
x.push(10);
var tspan = document.createElementNS('http://www.w3.org/2000/svg','tspan');
tspan.textContent = text[n - i - 1];
sintext.appendChild(tspan);
var h = Math.round(360 / 26 * i);
tspan.setAttribute('fill','hsl(' + h + ',100%,100%)');
function arrange(t){
y = [];
var ly = 0,cy;
for(i = 0;i < n; ++i){
cy = -s * Math.sin(w* i *20 +t);
y.push(cy - ly);
ly = cy;
function render(){
sintext.setAttribute('dx',x.join(' '));
sintext.setAttribute('dy',y.join(' '));
function frame(){
t += 0.01;
arrange(t);
render();
requestAnimationFrame(frame);
arrange(0);
render();
frame();
</script>
</body>
</html>
<tspan>标签
<text x="100" y="100" style="font-size:50px; font-family:'Arial';">
<tspan fill="red">AB</tspan><tspan stroke="green" stroke-width="2" fill="none">CDE</tspan>
</text>
5.3.1 使用方法
<path id="path1" d="M 100 200 Q 200 100 300 200 T 500 200" stroke="rgb(0,255,0)" fill="none" />
<text style="font-size: 24px;">
<textPath xlink:href="#path1">
这个文字先上去又下来了!
</textPath>
</text>
5.3.2 布局原理
<svg width="1000" height="1000">
<path id="path1" d="M100 200Q200 100 300 200T500 200" stroke="rgb(0,255,0)" fill="none"></path>
<text style="font-size:24px;" x="0" y="0" text-anchor=“start” >
//这里的x控制文字的水平位置,y没有实际作用;text-anchor表示文字的起始位置,三个值:start(文本起点与路径起始点对齐)、minddle(文本中点与路径起始点对齐)、end;
<textPath xlink:href="#path1" startOffset=“0%”>
//startOffset:0~100%,文本在路径上的位置,50%表示在路径的中点
这个文字先上去又下来了!
</textPath>
</text>
dx、dy属性
切线和法线方向的偏移
<svg width="1000" height="1000">
<path id="path1" d="M100 200Q200 100 300 200T500 200" stroke="rgb(0,255,0)" fill="none"></path>
<text style="font-size:24px;" x="0" y="0" text-anchor=“start” >
<textPath dominant-baseline="central" startOffset=“50%” xlink:href="#path1" >
<tspan> 这个文字先</tspan>
<tspan dy="-30" dx="20" fill="blue">上去</tspan>
<tspan dy="30" dx="20" > ,又</tspan>
<tspan dy="30" fill="red">下来</tspan>
<tspan dy="-30">了!</tspan>
</textPath>
</text>
target 指定打开目标
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<a xlink:href="http://www.baidu.com" xlink:title="ceshi" target="_blank">
<circle cx="300" cy="150" r="50" fill="rgba(0, 255, 0, .5)" stroke="rgb(0, 200, 0)" stroke-width="2"></circle>
当SVG独立存在时,需要xmlns:xlink="http://www.w3.org/1999/xlink"
声明xlink的名称空间。
六、图形引用、裁切和蒙版
6.1 <use>标签创建图形引用
xlink:href="#id"
<use xlink:href="#real" transform="scale(1,-1)" />
6.2 <cilp>标签裁切图形
clip-path="url(#clip-id)"
<clipPath id="light-clip">
<polygon points="0 0 -301 -15 -301 15" fill="rgba(255,0,0,.5)">
<!-- 添加动画 -->
<animateTransform attributeName="transform" attributeType="XML" type="rotate" form="0" to="360" dur="10s" repeatCount="indefinite"></animateTransform>
</polygon>
<circle cx="0" cy="0" r="4"></circle>
</clipPath>
<!-- 使用clip-path="url(#light-clip)"取三角形和椭圆的交集 -->
<ellipse cx="0" cy="0" rx="300" ry="100" fill="url(#light-color)" clip-path="url(#light-clip)"></ellipse>
6.3 <mask> 标签创建蒙版
mask="url(#mask-id)"
<g id="reflact" transform="translate(0 100)" mask="url(#fading)">
<!-- 绘制线性渐变 -->
<linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="rgba(255,255,255,.3)"></stop>
<stop offset="0.5" stop-color="rgba(255,255,255,0)"></stop>
</linearGradient>
<mask id="fading">
<rect x="-400" y="-50" width="800" height="300" fill="url(#fade)"></rect>
</mask>
</defs>
<use xlink:href="#real" transform="scale(1,-1)" />
七、SVG动画
7.1 动画原理
<animate>、<animateTransform>、<animateMotion>...
动画元素、属性定位以及动画参数设置
‣ attributeName、attributeType
‣ form、to、dur、repeatCount、fill...
‣ calcMode...
7.2.1 定位动画目标
internal Resource Identifier定位
<animate xlink:href="url(#rect1)"></animate>
被包含在目标元素里
<rect x="0">
<animate></animate>
</rect>
7.2.2 基本动画<animate>
设置要进行动画的属性以及变化范围、时间长度
<animate xlink:href="url(#rect1)">
attributeType="XML"
attributeName="x"
from="10"
to="110"
dur="3s"
</animate>
实例,写一个从左到右移动,颜色由红色变为黄色的动画:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">
<rect x="100" y="100" width="100" height="100" fill="red">
<animate attributeType="XML" attributeName="x" from="100" to="500" dur="3s" fill="freeze" > </animate>
<-- repeatCount="indefinite" //无限次重复,可是设置整数-->
<animate attributeType="XML" attributeName="fill" from="red" to="yellow" dur="3s" fill="freeze"></animate>
</rect>
让矩形来回摆动且颜色跟着切换:
<animate id="goRight" attributeType="XML"
begin="0; goLeft.end + 1s"
attributeName="x" from="100" to="500" dur="3s" fill="freeze"></animate>
<animate id="goLeft" attributeType="XML"
begin="goRight.end + 1s"
attributeName="x" from="500" to="100" dur="3s" fill="freeze"></animate>
<animate id="toYellow" attributeType="XML" attributeName="fill"
begin="0; toRed.end + 1s"
from="red" to="yellow" dur="3s" fill="freeze"></animate>
<animate id="toRed" attributeType="XML" attributeName="fill"
begin="toYellow.end + 1s"
from="yellow" to="red" dur="3s" fill="freeze"></animate>
7.2.3 变换动画 <animateTransform>
transform
<animateMotion xlink:href="url(#rect1)"
path="M 0 0 h 100 v 100 h -100 v -100 z"
rotate="auto"
dur="3s">
</animateMotion>
<svg viewBox="-400 -400 800 800">
<rect x="-25" y="-25" width="50" height="50" fill="rgba(0,255,255,.6)">
<animateMotion path="M 0 0 L 100 100 A 200 200 0 1 0 0 -100" dur="3s" rotate="auto" fill="freeze"></animateMotion>
</rect>
<path id="motion-path" d="M 0 0 L 100 100 A 200 200 0 1 0 0 -100" fill="none" stroke="gray"></path>
<animateMotion dur="3s" rotate="auto">
<mpath xlink:href="#motion-path"></mpath>
</animateMotion>
7.3 脚本动画 ScriptingAnimation
先看实例:SVG Scripting Example
<svg width="500" height="100">
<rect id="rect1" x="10" y="10" width="50" height="80"
style="stroke:#000000; fill:none;"/>
<input id="button1" type="button" value="Change Dimensions"
onclick="changeDimensions()"/>
<script>
function changeDimensions() {
document.getElementById("rect1").setAttribute("width", "100");
</script>
点击按钮,矩形会的宽度会增加到100,在线查看效果
通过ID获取对SVG元素的引用,更改属性值:setAttribute()
var svgElement = document.getElementById("rect1");
svgElement.setAttribute("width","100")
也可以通过getAttribute()获取属性的值:
var svgElement = document.getElementById("rect1");
var width = svgElement.getAttribute("width");
您可以通过元素的style属性引用给定的CSS属性来更改SVG元素的CSS属性。
var svgElement = document.getElementById("rect1");
svgElement.style.stroke = "#ff0000";
你也可以设置CSS属性只需要把元素名字写在svgElement.style.
后面就可以了
var setElement = document.getElementById("rect1")
var stroke = svgElement.style.stroke;
上面段代码会读取stroke的值。
如果CSS属性名字包含破折号,比如:stroke-width,就需要用[""]
包起来,这样做是因为带有短划线的属性名称在JavaScript中无效。
例如,你不能这样写element.style.stroke-width
,而是要写成:element.style['stroke-width']
如果需要,您可以直接在SVG中将事件侦听器添加到SVG形状。 你这样做就像使用HTML元素一样。 以下是添加onmouseover和onmouseout事件侦听器的示例:
<rect x="10" y="10" width="100" height="75"
style="stroke: #000000; fill: #eeeeee;"
onmouseover="this.style.stroke = '#ff0000'; this.style['stroke-width'] = 5;"
onmouseout="this.style.stroke = '#000000'; this.style['stroke-width'] = 1;" />
你还可以使用addEventListener()
函数方法:
var svgElement = document.getElementById("rect1");
svgElement.addEventListener("mouseover", mouseOver);
function mouseOver() {
alert("event fired!");
本示例将一个名为mouseOver的事件侦听器函数添加到mouseover事件。 这意味着,只要用户将鼠标悬停在SVG元素上,就会调用事件侦听器函数。
动画的暂停与启动
为了动画SVG形状,您需要重复调用JavaScript函数。 该功能改变形状的位置或尺寸。 当函数被重复调用并且间隔非常短时,形状的位置或尺寸也会以非常短的时间间隔更新,这使得形状呈现动画效果。
这里是一个SVG脚本动画的例子。 示例下面显示了创建它的代码。 点击SVG图像下面的两个按钮来启动和停止动画。
<svg width="500" height="100">
<circle id="circle1" cx="20" cy="20" r="10"
style="stroke: none; fill: #ff0000;"/>
<script>
var timerFunction = null;
function startAnimation() {
if(timerFunction == null) {
timerFunction = setInterval(animate, 20);
function stopAnimation() {
if(timerFunction != null){
clearInterval(timerFunction);
timerFunction = null;
function animate() {
var circle = document.getElementById("circle1");
var x = circle.getAttribute("cx");
var newX = 2 + parseInt(x);
if(newX > 500) {
newX = 20;
circle.setAttribute("cx", newX);
</script>
<input type="button" value="Start Animation" onclick="startAnimation();">
<input type="button" value="Stop Animation" onclick="stopAnimation();">
两个HTML按钮都附有一个onclick监听器。 这些监听器调用启动和停止动画的startAnimation()和stopAnimation()函数。 动画是通过设置一个每20毫秒调用一次animate()函数的计时器来启动的。 通过再次清除该定时器功能停止动画。
动画是在animate()函数内执行的。 首先,函数通过document.getElementById()函数获取对SVG图像中<circle>元素的引用。 然后读取该圆圈的cx属性并将其转换为数字。 然后将2添加到cx值。 如果新的x值大于500,则重置为20.最后,将新的x值放回到<circle>元素的cx属性中。 这个圆被移动到一个新的x位置。
利用JS创建动画
requestAnimationFrame(update)
示例 力导向图