SVG

SVG: scalable vector graphics

  1、使用XML定义图形

  2、图像可伸缩,尺寸更小,放大或者是改变尺寸时图片质量不会有所损失

  3、除了IE需要安装插件,其他浏览器都支持SVG文件

  4、svg文件需以.svg后缀保存

  5、svg文件可以通过标签嵌入html文档:<embed>、<object>或者是<iframe>(注意使用object时不能使用脚本)

  6、html5允许svg标签直接在HTML文件中使用


预定义形状:

  

<rect> : 矩形 x、y分别是距离左侧和顶端的位置;rx、ry用于产生圆角;fill-opacity和stroke-opacity分别定义填充颜色和笔触颜色的透明度

<circle>: cx、cy定义原点坐标(忽略时为0,0),r圆半径

<eclipse>:cx、cy原点坐标 rx、xy半径

<line>: x1、x2、y1、y2 x方向和开始和结束和y方向的开始和结束

<polyline>: points定义每个点的x左边和y坐标

<polygon>:多边形 同polyline用points定义坐标

<path> : 路径,稍微有点复杂如下: 大写表示绝对定位、小写表示相对定位  
    M
= moveto     L = lineto     H = horizontal lineto     V = vertical lineto     C = curveto     S = smooth curveto     Q = quadratic Belzier curve     T = smooth quadratic Belzier curveto     A = elliptical Arc     Z = closepath

滤镜:

1、可在每个svg元素上定义多个滤镜,

2、需在<defs>标签中嵌套定义svg滤镜,将filter标签嵌套在defs中eg:

<defs>
<filter id = "gaus_blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="3"/> //in定义由整个图像创建效果
</filter>
</defs>

3、用filter定义的同一滤镜可以被多个元素使用,使用时filter:url方式eg:引用上面的滤镜<filter="url(#gaus_blur)">

4、支持的滤镜如下:

feBlend
feColorMatrix
feComponentTransfer
feComposite
feConvolveMatrix
feDiffuseLighting
feDisplacementMap
feFlood
feGaussianBlur
feImage
feMerge
feMorphology
feOffset
feSpecularLighting
feTile
feTurbulence
feDistantLight
fePointLight
feSpotLight

渐变: 支持线性渐变和放射渐变

<linearGradient>:线性渐变,也是必须嵌套在<defs>标签中,x1,x2,y1,y2定义渐变的开始和结束

eg:

<defs>
<linearGradient id="orange_red" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1"/>
</linearGradient>
</defs>

<ellipse cx="200" cy="190" rx="85" ry="55"
style="fill:url(#orange_red)"/>

<radialGradient>: 放射性渐变,也是必须嵌套在<defs>标签中

eg:

<defs>
<radialGradient id="grey_blue" cx="50%" cy="50%" r="50%"
fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(200,200,200);
stop-opacity:0"/>
<stop offset="100%" style="stop-color:rgb(0,0,255);
stop-opacity:1"/>
</radialGradient>
</defs>

<ellipse cx="230" cy="200" rx="110" ry="100"
style="fill:url(#grey_blue)"/>

例子:

eg1:svg文件形式

<?xml version="1.0">

<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>
//stroke控制轮廓

结果:红色圆,边线为黑色

eg2:饼图:

/*
    创建一个svg元素,并在其中绘制一个饼图
    参数:
        data:用于绘制的数字类型的数组,数组的每一项都表示饼状图的一个栔
        width,height: SVG图形的高和宽,单位为像素
        cx、cy、r:饼状图的圆心及半径
        colors:包含html颜色信息的数组,每种颜色代表饼状图的每一个栔的颜色
        labels:标签数组,说明饼状图的每一个栔代表的含义
        lx、ly:饼状图的左上角
*/


function pieChart(data, width, height, cx, cy, r, colors, labels, lx, ly){
    //svg元素的xml命名空间
    var svgns = "http://www.w3.org/2000/svg"; 

    //创建svg元素
    var chart = document.createElementNS(svgns, "svg:svg"); 
    chart.setAttribute("width", width);
    chart.setAttribute("height", height);
    chart.setAttribute("viewBox", "0 0 " + width + " " + height); //viewBox为坐标系

    //累加data的值,以便于知道饼状图的大小
    var total = 0;
    for(var i = 0; i < data.length; i++){
        total += data[i];
    }

    //计算饼状图的每个分片的大小,角度以弧度制计算
    var angles = [];
    for(var i = 0; i < data.length; i++){
        angles[i] = data[i]/total*Math.PI*2;      
    }

    //栔的开始位置和结束位置以及和圆交汇的两个点的坐标位置,12点钟放
    var startAngle = 0, 
        endAngle,
        x1,
        y1,
        x2,
        y2;
    for(var i = 0; i < data.length; i++){
        endAngle = startAngle + angles[i];
        x1 = cx + r*Math.sin(startAngle);
        y1 = cy - r*Math.cos(startAngle);
        x2 = cx + r*Math.sin(endAngle);
        y2 = cy - r*Math.cos(endAngle);

        //判断角度是否大于半圆
        var big = 0;
        if(endAngle - startAngle > Math.PI){
            big = 1;
        }

        //使用<svg:path>描述栔,使用createElementNS创建该元素
        var path = document.createElementNS(svgns, "path");

        //设置路径
        var d = "M " + cx + "," + cy + " L " + x1 + "," + y1 + " A " + r + "," + r + " 0 " + big + " 1 " + x2 + "," + y2 + " Z";
        path.setAttribute("d", d);
        path.setAttribute("fill", colors[i]); 
        path.setAttribute("stroke", "black"); 
        path.setAttribute("stroke-width", "2");
        chart.appendChild(path);

        //下一个栔从此处开始
        startAngle = endAngle;

        //绘制小方格表示图例
        var icon = document.createElementNS(svgns, "rect");
        icon.setAttribute("x", lx);
        icon.setAttribute("y", ly + 30*i);
        icon.setAttribute("width", 20);
        icon.setAttribute("height", 20);
        icon.setAttribute("fill", colors[i]);
        icon.setAttribute("stroke", "black");
        icon.setAttribute("stroke-width", "2");
        chart.appendChild(icon);

        //为右边的小方格添加标签
        var label = document.createElementNS(svgns, "text");
        label.setAttribute("x", lx + 30);
        label.setAttribute("y", ly + 30*i + 18);
        label.setAttribute("font-family", "sans-serif");
        label.setAttribute("font-size", "16");

        label.appendChild(document.createTextNode(labels[i]));
        chart.appendChild(label);
    }
    
    return chart;
    
}
<body onload = "document.body.appendChild(pieChart([12,23,34,45], 640, 400, 200, 200, 150,['red', 'blue', 'yellow', 'green'],['North', 'South', 'East', 'West'],400,100))">

结果:

 eg3:时钟:

function svgClock(){
    var now = new Date();
    var min = now.getMinutes();
    var hour = (now.getHours() % 12) + min/60;
    var minAngle = min * 6; //每6度一分钟
    var hourAngle = hour * 30; //每30度一小时

    var minHand  = document.getElementById("minuteHand");
    var hourHand = document.getElementById("hourHand");
    var clock = document.getElementById("clock");

    minHand.setAttribute("transform", "rotate(" + minAngle + ",50,50)");
    hourHand.setAttribute("transform", "rotate(" + hourAngle + ",50,50)");
    clock.setAttribute("fill","#eef" );

    //每一分钟更新下时间
    setTimeout(svgClock, 60000);
}
#clock {
    stroke: black;  /*stroke定义轮廓颜色*/
    stroke-linecap: round;  /*圆角*/
    fill: #eef; /*浅蓝色背景*/
}

#face {
    stroke-width : 3px; /*时钟的外边框*/
}

#ticks {
    stroke-width: 2; /*标记每个小时的线段*/
}

#hourHand {
    stroke-width: 5px;.
}

#minuteHand {
    stoke-width: 3px;
}

#numbers {
    font-family: sans-resif;
    font-size: 7pt;
    font-weight: bold;

    text-anchor: middle;
    stroke: none;
    fill: black;
}
<body onload="svgClock()">
    <svg id="clock" viewBox="0 0 100 100" width="500" height="500">
        <defs>
            <filter id="shadow" x="-50%" y="-50%" width="500" height="500">
                <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"> <!-- 设置滤镜 -->
                <feOffset in="blur" dx="1" dy="1" result="shadow"/>
                <feMerge>
                    <feMergeNode in="SourceGraphic"/>
                    <feMergeNode in="shadow"/>
                </feMerge>
            </filter>
        </defs>
        
        <circle id="face" cx="50" cy="50" r="45"/> <!-- 钟面 -->
        
        <g id="ticks">  <!-- 12小时的刻度 g用于将元素组合 -->
            <line x1="50" y1="5.000" x2="50.00" y2="10.00"/>
            <line x1="72.50" y1="11.03" x2="70.00" y2="15.36"/>
            <line x1="88.97" y1="27.50" x2="84.64" y2="30.00"/>
            <line x1="95.00" y1="50.00" x2="90.00" y2="50.00"/>
            <line x1="88.97" y1="72.50" x2="84.64" y2="70.00"/>
            <line x1="72.50" y1="88.97" x2="70.00" y2="84.64"/>
            <line x1="50.00" y1="95.00" x2="50.00" y2="90.00"/>
            <line x1="27.50" y1="88.97" x2="30.00" y2="84.64"/>
            <line x1="11.03" y1="72.50" x2="15.36" y2="70.00"/>
            <line x1="5.000" y1="50.00" x2="10.00" y2="50.00"/>
            <line x1="11.03" y1="27.50" x2="15.36" y2="30.00"/>
            <line x1="27.50" y1="11.03" x2="30.00" y2="15.36"/>
        <g/>
        
        <g id="numbers"> <!-- 标记重要的刻度值,3,6,9,12等 -->
            <text x="50" y="18">12</text>
            <text x="85" y="53">3</text>
            <text x="50" y="88">6</text>
            <text x="15" y="53">9</text>
        </g>
        
        <g id="hands" > <!-- 初始绘制成竖直的指针,之后通js旋转,并且给指针加上阴影 -->
            <line id="hourHand"  x1="50" y1="50" x2="50" y2="24"/>
            <line id="minuteHand"  x1="50" y1="50" x2="50" y2="20"/>
        </g>
    </svg>
</body>

结果:

原文地址:https://www.cnblogs.com/wishyouhappy/p/3791670.html