SVG 基礎(chǔ)

使用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標簽

<p>
    <svg>
        ...
    </svg>
</p>
  • 1.1.4 作為CSS背景

.container{
  background: white url(bg.svg) repeat;
}



[2]

1.2 基本圖形和屬性

  • 基本圖形

<rect>
<circle>
<ellipse>
<line>
<polyline>
<polygon>

  • 基本屬性

fill
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 ....


1.2.1 <rect>

<rect x="100" y="100" width="200" height="100" rx="30" ry="30" fill="red" />

rx\ry表示圓角度數(shù)可霎,如果只給一個值魄鸦,另一個也會用到同一個值。


1.2.2 <circle>

<circle cx="100" cy="100" r="50" fill="red" />

cx/cy表示圓心的位置


1.2.3 <ellipse>

<ellipse cx="100" cy="100" rx="80" ry="40" fill="red"/>


1.2.4 <line>

<line x1="100" y1="200" x2="400" y2="100" style="stroke:red" />


1.2.5 <polyline>

<polyline points="50 200 200 50 400 200 200 400" fill="none" stroke="red" />


1.2.6 <polygon>

<polygon points="50 200 200 50 400 200 200 400"fill="none" stroke="red" />


1.2.7 填充癣朗、描邊和變形

<rect x="100" y="100" width="400" height="200" fill="#FFB3AE" stroke="#971817" stroke-width="10" transform="rotate(30)" />


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>

[3]

1.3基本操作API

  • 創(chuàng)建圖形
document.createElementNS(ns,tagName)
  • 添加圖形
element.appendChild(childElement)
  • 設(shè)置/獲取屬性
element.setAttribute(name,value)
element.getAttribute(name)

[4]

綜合實例:簡單的SVG編輯器

點擊這里查看源代碼

[5]

二拾因、SVG中的坐標系統(tǒng)與坐標變換

[6]

2.1 SVG的世界、視野旷余、視窗的概念

  • 世界是無窮大的
  • 視野就是觀察世界的一個矩形區(qū)域


  • width,height - 控制視窗
  • SVG代碼 - 定義世界
  • viewBox绢记,preserveAspectRadtio - 控制視野
    查看完整代碼
<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>

[7]

2.2 SVG中的圖形分組

  • <g>標簽來創(chuàng)建分組
  • 屬性繼承
  • tranform屬性定義坐標變換
  • 可以嵌套使用
<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>
    </g>
</svg>
整體位移

[8]

2.3 坐標系統(tǒng)概述

  • 笛卡爾直角坐標系
  • 原點
  • 互相垂直的兩條數(shù)軸
  • 角度定義


    角度是順時針

[9]

2.4 四個坐標系

  • 2.4.1用戶坐標系(User Coordinate)
    世界的坐標系--原始坐標系

  • 2.4.2自身坐標系(Current Coordinate)
    每個圖形元素或分組獨立與生俱來

  • 2.4.3前驅(qū)坐標系(Previous Coordinate)
    父容器的坐標系
    Ouser就是前驅(qū)坐標系
    Oa就是自身坐標系


C、D的前驅(qū)坐標系:OB正卧,重合是因為C蠢熄、D沒有變化(translate)
C的自身坐標系是Oc

  • 2.4.4參考坐標系(Reference Coordinate)
    使用其他坐標系來考究自身的情況時使用

    相對世界坐標系Ouser時,矩形的坐標就是(50炉旷,50)签孔,此時Ouser就是參考坐標系

[10]

2.5 坐標變換

  • 2.5.1 定義
    -數(shù)學上,坐標變換是采用一定的數(shù)學方法將一個坐標系的坐標變換為另一個坐標系的坐標過程窘行。
    -SVG中坐標變換是對一個坐標系到另一個坐標系的變換的描述

  • 2.5.2 線性變換

  • 2.5.3 線性變換列表
后面的變換乘在后面和前面效果會不一樣
  • 2.5.4 transform屬性
    -前驅(qū)坐標系:父容器的坐標系
    -transform屬性:定義前驅(qū)坐標系到自身坐標系的線性變換
    -語法:
rotate(<deg>)*
translate(<x>,<y>)*
scale(<sx>,<sy>)*
matrix(<a>,<b>,<c>,<d>,<e>,<f>)*

實例:查看原代碼

<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="600" viewBox="-200.5 -100.5 1000 600">
        <defs>
            <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>
            </g>
        </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>
            </g>

            <g id="d" stroke="orange" fill="orange" transform="translate(150, 150)">
                <text x="5" y="20">d</text>
                <use xlink:href="#coord"></use>
            </g>
        </g>
    </svg>
transform



[11]

三饥追、顏色、漸變和筆刷

[12]

3.1 SVG-RGB和HSL

  • 都是CSS3支持的顏色表示方法

3.1.1 RGB

  • 表示方式:rgb(r,g,b)或#rrggbb
  • 優(yōu)勢:顯示器容易解析
  • 劣勢:不符合描述顏色的習慣


3.1.2 HSL

  • 三個分量分別表示顏色罐盔、飽和度但绕、亮度
  • 格式:hsl(h,s%,l%)
  • 取值范圍:
    h: [0,359]
    s, l : [0,100]


3.1.2 透明度

  • rgba(r,g,b,a)和hsla(h,s%,l%,a)表示帶透明度的顏色
  • opacity屬性表示元素的透明度
  • a和opacity的取值范圍: [0,1]


3.1.4 在SVG中應(yīng)用顏色

<rect fill="rgb(255,0,0)" opacity="0.5">
<rect stroke="hsla(0,50%,60%,0.5)">
  • 互相轉(zhuǎn)換的原理

[13]

3.2 線性漸變和徑向漸變

3.2.1 線性漸變:

  • <linerGradient>和<stop>
  • 定義方向
  • 關(guān)鍵點位置及顏色
  • gradientUnits
<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <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>

3.2.2 徑向漸變:

  • <linerGradient>和<stop>
  • 定義方向
  • 關(guān)鍵點位置及顏色
  • gradientUnits
  • 焦點位置
<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <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" />
</svg>

[14]

3.3 使用筆刷

  • 繪制紋理
  • <pattern>標簽
  • patternUnits和patternContentUnits
    pattern 的屬性
    patternUnits:
    objectBoundingBox : (默認)為容器百分比
    userSpaceOnUse : width 和 height 以世界坐標系為準,為寬度惶看、高度
    patternContentUnits:
    userSpaceOnUse : (默認)為以世界坐標系為準
    objectBoundingBox : pattern 的子元素(這里指 circle 和 polygon捏顺,尺寸屬性為 rect 的百分比)
    一般情況下 patternContentUnits 為 objectBoundingBox 時,patternUnits 也為 objectBoundingBox纬黎,好處理
<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <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>
</svg>
<pattern id="p1" x="0" y="0" width="0.2" height="0.2" patternUnits="userSpaceOnUse">   

他還有個patternContentUnits="objectBoundingBox/userSpaceOnUse"屬性:

<pattern id="p1" x="0" y="0" width="0.2" height="0.2" patternUnits="objectBoundingBox" patternContentUnits="objectBoundingBox"> 

[15]

四草丧、Path高級教程

[16]

4.1 Path概述

<path d="M0,0L10,20C30-10,40,20,100,100" stroke="red">
<tiger.svg>

  • 以下path字符串都是一樣的

<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命令匯總
    凡是出現(xiàn)大寫字母表示后續(xù)坐標為絕對坐標, 凡是小寫字母都代表相對于上一個坐標的相對位移莹桅。 Z 同 z 無差別昌执,因為表示閉合,其后不用跟坐標诈泼。
命令 含義
M/m (x,y)+ 移動當前位置到(x, y) (小寫表示相對于上個坐標的位移, 下同)
L/l (x,y)+ 畫一條直線到(x, y)
H/h (x)+ 水平畫一條直線到 x
V/v (y)+ 豎直畫一條直線到 y
Z/z 閉合當前路徑
C/c (cx1 cy1 cx2 cy2 x y)+ 從當前點畫一條到(x, y)的三次貝塞爾曲線, 曲線的開始控制點和終點控制點為別為 (cx1, cy1), (cx2, cy2).
S/s (cx2 cy2 x y)+ 此命令只能跟在 C 命令后使用, 假設(shè) C 命令生成曲線 s, S 命令的作用是再畫一條到 (x, y)的三次貝塞爾曲線, 曲線的終點控制點是 (cx2, cy2), 曲線的開始控制點是 s 的終點控制點關(guān)于 s 終點的對稱點.
Q/q (cx,cy,x,y)+ 從當前點畫一條到(x, y)的二次貝塞爾曲線, 曲線的控制點為(cx, cy)
T/t (x,y)+ 此命令只能跟在 Q 命令后使用, 假設(shè) Q 命令生成曲線 s, T 命令的作用是從 s 的終點再畫一條到(x y)的二次貝塞爾曲線, 曲線的控制點為 s 控制點關(guān)于 s 終點的對稱點. T 命令生成的曲線會非常平滑
A(a) rx ry x-axis-rotation large-arc sweep x y 畫一段到(x,y)的橢圓弧. 橢圓弧的 x, y 軸半徑分別為 rx,ry. 橢圓相對于 x 軸旋轉(zhuǎn) x-axis-rotation 度. large-arc=0表明弧線小于180讀, large-arc=1表示弧線大于180度. sweep=0表明弧線逆時針旋轉(zhuǎn), sweep=1表明弧線順時間旋轉(zhuǎn). 具體解釋看如何繪制橢圓弧
  • path命令基本規(guī)律:
  • 區(qū)分大小寫:大寫表示坐標參數(shù)為絕對位置懂拾,值決定位置;小寫則為相對位置铐达,值決定長度
  • 最后的參數(shù)表示最終要到達的位置
  • 上一個命令結(jié)束的位置就是下一個命令開始的位置
  • 命令可以重置參數(shù)表示重復執(zhí)行同一條命令

[17]

4.2 移動和直線命令

  • M (x,y)+ 移動畫筆岖赋,后面如果有重復參數(shù),會當做是L命令處理
  • L (x,y)+ 繪制直線到指定位置
  • H (x)+ 繪制水平線到指定的 X 位置
  • V (y)+ 繪制豎線到指定的 Y 位置
  • m瓮孙、l唐断、h选脊、v使用相對位置繪制,值決定線的長度
    例:
M 200 200 h 300 v100 l 100 -100 M 0 0 L 200 200
M 200 200 h 300 v100 l 100 -100 M 0 0 L 200 200

[18]

4.3 弧線命令

A(rx,ry,xr,laf,sf,x,y) - 繪制弧線

最復雜的命令:

  • rx - (radius-x)弧線所在橢圓的X半軸長
  • ry - (radius-y)弧線所在橢圓的Y半軸長
  • xr - (xAxis-rotation)弧線所在橢圓的長軸角度脸甘,那么 x-axis-rotation 又是什么意思呢? b, c, d, e 產(chǎn)生的前提是 橢圓的 x 軸與用戶坐標系的 x 軸是平行的.
    F 圖表示橢圓 x 軸相對于用戶坐標系的 x 軸旋轉(zhuǎn)30度所產(chǎn)生的橢圓弧. 灰色的部分表示原來產(chǎn)生的橢圓弧.
  • laf - (large-arc-flag)是否選擇弧長較長的那一段
  • sf - (sweep-flag)是否選擇逆時針方向的那一段弧
  • x,y - 弧的終點位置
x-axis-rotation=30
M 200 200 A 200 100 216 1 1 300 300
M 200 200 h 100 l -100 100 v -100 M 300 200 A 100 100 0 0 1 200 300

[19]

4.4 貝塞爾曲線命令

點擊查看貝茲曲線

直線的軌跡

二次貝塞爾曲線
三次貝塞爾曲線
四次貝塞爾曲線


4.4.1 二次貝塞爾曲線命令

  • 起始點
  • 結(jié)束點
  • 控制點
  • 控制線
M x0 y0 Q x1 y1 x y


4.4.2 三次貝塞爾曲線命令

  • 起始點
  • 結(jié)束點
  • 控制點
  • 控制線
M x0 y0 C x1 y1 x2 y2 x y
http://myst729.github.io/bezier-curve/
關(guān)于三次貝塞爾曲線的例子


4.4.3 光滑曲線

  • T: Q的光滑版本
    C1是上一段曲線的控制點關(guān)于當前去先期試點的鏡像位置
  • S: C的簡化版本
    C1是上一段曲線的控制點2關(guān)于當前曲線起始點的鏡像位置

M 100 200 C 100 100 250 100 250 200 S 400 300 400 200
S 400 300 400 200 代替了 C 250 300 400 300 400 200


[20]

4.5 回顧和思考

  • Path命令的作用是什么恳啥,Path字符串的格式是什么?
  • 一共有多少個Path命令丹诀,它們分別得參數(shù)是什么钝的?
  • 如何求貝塞爾曲線的長度,如何球整個Path的長度
  • 如何求一個Path的子路徑铆遭?
  • 如何求兩個Path的補間硝桩?
上面的C的高度為什么是100?圓的半徑為75枚荣,事實證明三次貝塞爾曲線畫出來的也并非是一個標準圓



[21]

五碗脊、SVG文本

[22]

5.1 <text>和<tspan>創(chuàng)建文本

  • x和y屬性 - 定位標準
  • dx和dy屬性 - 字形偏移
  • style屬性 - 設(shè)置樣式

SVG 畫網(wǎng)格

<svg xmlns="http://www.w3.org/2000/svg">
    <defs>
        <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>
</svg>
<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>     //輔助線
dx="20 40 60 80 100" dy="20 40 60 80 100"

實例朝聋,使用 正弦曲線 讓文字動起來

<!DOCTYPE html>
<html>
<head>
<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>
<body>
<!-- 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>
</svg>
<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>
<tspan>
  • dy屬性在tspan上設(shè)置之后竹海,tspan的屬性會傳遞給后面足绅,并且text上的dx真竖、dy就會被覆蓋 而且帅刀,里初。

[23]

5.2 垂直居中問題

  • text-anchor - 水平居中屬性
  • dominant-baseline屬性
  • 模擬居中
    源代碼

垂直水平居中

查看效果

[24]

5.3 <textPath>讓文本在指定路徑上排列

  • 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 布局原理

    渲染原理

  • 5.3.3 定位屬性x,y,dx,dy的作用

  • x芒澜、text-anchor和startOffset屬性
    確定排列起始位置
<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>
</svg>
  • dx笛园、dy屬性
    切線和法線方向的偏移
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>
</svg>
  • 5.3.4 腳本控制
  • setAttributeNS()方法設(shè)置 xlink:href屬性
  • 把文本節(jié)點替換為<textpath>
    源代碼
    查看演示

注意:超出路徑長度研铆,不會被渲染

[25]

5.4 <a>插入超鏈接

  • 可以添加到任意的圖形上
  • xlink:href 指定鏈接地址
  • xlink:title 指定連接提示
  • target 指定打開目標
<svg xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
    <a xlink: 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>
    </a>
</svg>

當SVG獨立存在時埋同,需要xmlns:xlink="http://www.w3.org/1999/xlink"聲明xlink的名稱空間。




[26]

六棵红、圖形引用凶赁、裁切和蒙版

6.1 <use>標簽創(chuàng)建圖形引用

用法

xlink:href="#id"

<use xlink:href="#real" transform="scale(1,-1)" />

[27]

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>

[28]

6.3 <mask> 標簽創(chuàng)建蒙版

mask="url(#mask-id)"

<g id="reflact" transform="translate(0 100)" mask="url(#fading)">
  <!-- 繪制線性漸變 -->
  <defs>
    <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)" />
</g>

查看源文件



[29]

七、SVG動畫

7.1 動畫原理

image.png



[30]

7.2 SMIL for SVG


7.2.1 定位動畫目標

  • internal Resource Identifier定位
<animate xlink:href="url(#rect1)"></animate>
  • 被包含在目標元素里
<rect x="0">
  <animate></animate>
</rect>



[31]

7.2.2 基本動畫<animate>

  • 設(shè)置要進行動畫的屬性以及變化范圍、時間長度
<animate xlink:href="url(#rect1)">
  attributeType="XML"
  attributeName="x"
  from="10"
  to="110"
  dur="3s"
</animate>

實例稚茅,寫一個從左到右移動纸淮,顏色由紅色變?yōu)辄S色的動畫:

<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"  //無限次重復,可是設(shè)置整數(shù)-->
    <animate attributeType="XML" attributeName="fill" from="red" to="yellow" dur="3s" fill="freeze"></animate>
  </rect>
</svg>

讓矩形來回擺動且顏色跟著切換:

<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>



[32]

7.2.3 變換動畫 <animateTransform>

transform 描述
translate(x,y) 平移:將用戶坐標系統(tǒng)的坐標原點移動到 (x, y)
scale(xFactor, yFactor) 縮放:將用戶坐標系統(tǒng)的xy軸單位長度分別乘 (xFactor, yFactor)倍
scale(factor) 縮放:同 scale(factor, factor)
rotate(angle,centerX,centerY) 旋轉(zhuǎn):將用戶坐標系統(tǒng)以 (centerX, centerY) 為旋轉(zhuǎn)中心順時針旋轉(zhuǎn) angle 度
rotate(angle) 旋轉(zhuǎn):同 rotate(angle, 0, 0)
skewX(angle) 傾斜:根據(jù)angle傾斜所有 x 軸坐標亚享,視覺上會看到 y 軸傾斜
skewY(angle) 傾斜:根據(jù)angle傾斜所有 y 軸坐標咽块,視覺上會看到 x 軸傾斜
matrix(a b c d e f) 矩陣變換:將坐標系統(tǒng)進行矩陣變換
  • 設(shè)置要進行動畫的屬性以及變化范圍、時間長度
<animateTransform xlink:href="url(#rect1)"
  attributeName="transform"
  attributeType="XML"
  type="translate"
  from="0 0"
  to="100 100"
  dur="3s">
</animateTransform>
<animateTransform 
  attributeName="transform"
  attributeType="XML"
  type="scale"
  from="1"
  to="3"
  dur="3s"
  fill="freeze">
</animateTransform>



[33]

7.2.4 軌跡移動 <animateMotion>

  • 設(shè)置軌跡路徑
<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>
</svg>
<animateMotion dur="3s"  rotate="auto">
  <mpath xlink:href="#motion-path"></mpath>
</animateMotion>




[34]

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;"/>
</svg>
<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";
你也可以設(shè)置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']

事件監(jiān)聽

如果需要,您可以直接在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()函數(shù)方法:

var svgElement = document.getElementById("rect1");
svgElement.addEventListener("mouseover", mouseOver);
function mouseOver() {
    alert("event fired!");
}

本示例將一個名為mouseOver的事件偵聽器函數(shù)添加到mouseover事件。 這意味著谢揪,只要用戶將鼠標懸停在SVG元素上蕉陋,就會調(diào)用事件偵聽器函數(shù)。

動畫的暫停與啟動

為了動畫SVG形狀拨扶,您需要重復調(diào)用JavaScript函數(shù)寺滚。 該功能改變形狀的位置或尺寸。 當函數(shù)被重復調(diào)用并且間隔非常短時屈雄,形狀的位置或尺寸也會以非常短的時間間隔更新村视,這使得形狀呈現(xiàn)動畫效果。

這里是一個SVG腳本動畫的例子酒奶。 示例下面顯示了創(chuàng)建它的代碼蚁孔。 點擊SVG圖像下面的兩個按鈕來啟動和停止動畫奶赔。

<svg width="500" height="100">
    <circle id="circle1" cx="20" cy="20" r="10"
            style="stroke: none; fill: #ff0000;"/>
</svg>

<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>
<br/>
<input type="button" value="Start Animation" onclick="startAnimation();">
<input type="button" value="Stop Animation" onclick="stopAnimation();">

查看演示
兩個HTML按鈕都附有一個onclick監(jiān)聽器。 這些監(jiān)聽器調(diào)用啟動和停止動畫的startAnimation()和stopAnimation()函數(shù)杠氢。 動畫是通過設(shè)置一個每20毫秒調(diào)用一次animate()函數(shù)的計時器來啟動的站刑。 通過再次清除該定時器功能停止動畫。

動畫是在animate()函數(shù)內(nèi)執(zhí)行的鼻百。 首先绞旅,函數(shù)通過document.getElementById()函數(shù)獲取對SVG圖像中<circle>元素的引用。 然后讀取該圓圈的cx屬性并將其轉(zhuǎn)換為數(shù)字温艇。 然后將2添加到cx值因悲。 如果新的x值大于500,則重置為20.最后勺爱,將新的x值放回到<circle>元素的cx屬性中晃琳。 這個圓被移動到一個新的x位置。


利用JS創(chuàng)建動畫

  • 核心思想
requestAnimationFrame(update)
  • 示例 力導向圖


查看完整代碼




目錄


  1. 一琐鲁、SVG基本概念
    ?1.1SVG的使用方式 ?

  2. ?1.2 基本圖形和屬性 ?

  3. ?1.3基本操作API ?

  4. ?綜合實例:簡單的SVG編輯器 ?

  5. 二卫旱、SVG中的坐標系統(tǒng)與坐標變換 ?

  6. ?2.1 SVG的世界、視野围段、視窗的概念 ?

  7. ?2.2 SVG中的圖形分組 ?

  8. ?2.3 坐標系統(tǒng)概述 ?

  9. ?2.4 四個坐標系 ?

  10. ?2.5 坐標變換 ?

  11. 三顾翼、顏色、漸變和筆刷 ?

  12. ?3.1 SVG-RGB和HSL ?

  13. ?3.2 線性漸變和徑向漸變 ?

  14. ?3.3 使用筆刷 ?

  15. 四奈泪、Path高級教程 ?

  16. ?4.1 Path概述 ?

  17. ?4.2 移動和直線命令 ?

  18. ?4.3 弧線命令 ?

  19. ?4.4 貝塞爾曲線命令 ?

  20. ?4.5 回顧和思考 ?

  21. 五暴构、SVG文本 ?

  22. ?5.1 <text>和<tspan>創(chuàng)建文本 ?

  23. ?5.2 垂直居中問題 ?

  24. ?5.3 <textPath>讓文本在指定路徑上排列 ?

  25. ?5.4 <a>插入超鏈接 ?

  26. 六、圖形引用段磨、裁切和蒙版
    ?6.1 <use>標簽創(chuàng)建圖形引用 ?

  27. ?6.2 <cilp>標簽裁切圖形 ?

  28. ?6.3 <mask> 標簽創(chuàng)建蒙版 ?

  29. 七取逾、SVG動畫 ?

  30. ?7.2 SMIL for SVG ?

  31. ??7.2.2 基本動畫<animate> ?

  32. ??7.2.3 變換動畫 <animateTransform> ?

  33. ??7.2.4 軌跡移動 <animateMotion> ?

  34. ?7.3 腳本動畫 ScriptingAnimation ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市苹支,隨后出現(xiàn)的幾起案子砾隅,更是在濱河造成了極大的恐慌,老刑警劉巖债蜜,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晴埂,死亡現(xiàn)場離奇詭異,居然都是意外死亡寻定,警方通過查閱死者的電腦和手機儒洛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狼速,“玉大人琅锻,你說我怎么就攤上這事。” “怎么了恼蓬?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵惊完,是天一觀的道長。 經(jīng)常有香客問我处硬,道長小槐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任荷辕,我火速辦了婚禮凿跳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疮方。我一直安慰自己控嗜,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布案站。 她就那樣靜靜地躺著躬审,像睡著了一般棘街。 火紅的嫁衣襯著肌膚如雪蟆盐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天遭殉,我揣著相機與錄音石挂,去河邊找鬼。 笑死险污,一個胖子當著我的面吹牛痹愚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛔糯,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拯腮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蚁飒?” 一聲冷哼從身側(cè)響起动壤,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎淮逻,沒想到半個月后琼懊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡爬早,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年哼丈,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筛严。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡醉旦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情髓抑,我是刑警寧澤咙崎,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吨拍,受9級特大地震影響褪猛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜羹饰,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一伊滋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧队秩,春花似錦笑旺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸟蟹,卻和暖如春乌妙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背建钥。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工藤韵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熊经。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓泽艘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親镐依。 傳聞我的和親對象是個殘疾皇子匹涮,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355