@(HTML5)[canvas與SVG]javascript
[TOC]css
HTML體系中,最經常使用的繪製矢量圖的技術是SVG和HTML5新增長的canvas元素。這兩種技術都支持繪製矢量圖和光柵圖。不過canvas更偏重於動畫的製做。因此,繪製矢量圖
的大任落到了SVG身上。html
可縮放矢量圖形(Scalable Vector Graphics,簡稱SVG)是一種使用XML來描述二維圖形的語言(SVG嚴格聽從XML語法)。 SVG容許三種類型的圖形對象:矢量圖形形狀(例如由直線和曲線組成的路徑)、圖像和文本。 能夠將圖形對象(包括文本)分組、樣式化、轉換和組合到之前呈現的對象中。 SVG 功能集包括嵌套轉換、剪切路徑、alpha 蒙板和模板對象。java
SVG既能夠說是一種協議,也能夠說是一門語言;既是HTML的一個標準元素,也是一種圖片格式。
算法
SVG與其它的圖片格式相比,有不少優勢(不少優勢來源於矢量圖的優勢):canvas
注意事項: SVG的元素和屬性必須按標準格式書寫,由於XML是區分大小寫的(這一點和html不一樣) SVG裏的屬性值必須用引號引發來,就算是數值也必須這樣作。
瀏覽器
<rect x="10" y="10" width="30" height="30"/>
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
複製代碼
這個元素有6個控制位置和形狀的屬性,分別是:bash
x:矩形左上角的座標(用戶座標系)的x值。app
y:矩形左上角的座標(用戶座標系)的y值。svg
width:矩形寬度。
height:矩形高度。
rx:實現圓角效果時,圓角沿x軸的半徑。
ry:實現圓角效果時,圓角沿y軸的半徑。
注意:rx與ry只設置了一個,另外一個值等於設置了的這個值
<circle cx="25" cy="75" r="20"/>
複製代碼
這個元素的屬性很簡單,主要是定義圓心和半徑:
r:圓的半徑。
cx:圓心座標x值。
cy:圓心座標y值。
<ellipse cx="75" cy="75" rx="20" ry="5"/>
複製代碼
這個是更加通用的圓形元素,你能夠分別控制半長軸和半短軸的長度,來實現不一樣的橢圓,很容易想到,當兩個半軸相等時,就是正圓形了。
rx:半長軸(x半徑)。
ry:半短軸(y半徑)。
cx:圓心座標x值。
cy:圓心座標y值。
<line x1="10" x2="50" y1="110" y2="150"/>
複製代碼
直線須要定義起點與終點便可:
x1:起點x座標。
y1:起點y座標。
x2:終點x座標。
y2:終點y座標。
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
複製代碼
折線主要是要定義每條線段的端點便可,因此只須要一個點的集合做爲參數:
points:一系列的用空格,逗號,換行符等分隔開的點。每一個點必須有2個數字:x值和y值。因此下面3個點 (0,0), (1,1)和(2,2)能夠寫成:"0 0, 1 1, 2 2"。
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>
複製代碼
這個元素就是比polyline元素多作一步,把最後一個點和第一個點連起來,造成閉合圖形。參數是同樣的。
points:一系列的用空格,逗號,換行符等分隔開的點。每一個點必須有2個數字:x值和y值。因此下面3個點 (0,0), (1,1)和(2,2)能夠寫成:"0 0, 1 1, 2 2"。路徑繪製完後閉合圖形,因此最終的直線將從位置(2,2)鏈接到位置(0,0)。
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>
複製代碼
這個是最通用,最強力
的元素了;使用這個元素你能夠實現任何其餘的圖形
,不只包括上面這些基本形狀,也能夠實現像貝塞爾曲線那樣的複雜形狀;此外,使用path能夠實現平滑的過渡線段,雖然也可使用polyline來實現這種效果,可是須要提供的點不少,並且放大了效果也很差。這個元素控制位置和形狀的只有一個參數:
d:一系列繪製指令和繪製參數(點)組合成。
中間的字母的意思:
M10 10
L10 10
H 90
V 90
Z
C x1 y1, x2 y2, x y
三次貝賽爾曲線
補充命令。S命令能夠用來建立與以前那些曲線同樣的貝塞爾曲線可是,若是S命令跟在一個C命令或者另外一個S命令的後面,它的第一個控制點,就會被假設成前一個控制點的對稱點。若是S命令單獨使用,前面沒有C命令或者另外一個S命令,那麼它的兩個控制點就會被假設爲同一個點。S x2 y2, x y
Q x1 y1, x y
三次貝賽爾曲線
補充命令。與S
有殊途同歸之妙。T命令前面必須是一個Q命令,或者是另外一個T命令,才能達到這種效果。須要注意的是,若是T單獨使用,那麼控制點就會被認爲和終點是同一個點,因此畫出來的將是一條直線。 T x y
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
前兩個參數分別是x軸半徑和y軸半徑,第三個參數表示弧形的旋轉狀況。large-arc-flag(角度大小) 和sweep-flag(弧線方向),large-arc-flag決定弧線是大於仍是小於180度,0表示小角度弧,1表示大角度弧。sweep-flag表示弧線的方向,0表示從起點到終點沿逆時針畫弧,1表示從起點到終點沿順時針畫弧。最後兩個參數是指定弧形的終點L,H,V爲小寫的時候便表示的是長度,爲大寫的表示的是座標
繪製指令分爲絕對座標指令和相對座標指令兩種,這兩種指令使用的字母是同樣的,就是大小寫不同,絕對指令使用大寫字母,座標也是絕對座標;相對指令使用對應的小寫字母,點的座標表示的都是偏移量。
這組指令的參數表明的是絕對座標。假設當前畫筆所在的位置爲(x0,y0),則下面的絕對座標指令表明的含義以下所示:
這個屬性使用設置的值畫圖形的邊框,使用起來也很直接,把顏色值賦給它就能夠了。注意:
stroke-opacity
,值的範圍是0到1。實際上,邊的狀況比圖形內部稍微複雜一點,由於邊除了顏色,還有"形狀"須要定義。
線的端點 - stroke-linecap屬性 這個屬性定義了線段端點的風格,這個屬性可使用butt,square,round
三個值。
線的鏈接 - stroke-linejoin屬性 這個屬性定義了線段鏈接處的風格,這個屬性可使用miter,round,bevel三個值。
線的虛實 - stroke-dasharray屬性 這個屬性能夠設置線段採用何種虛實線。這個屬性是設置一些列數字,不過這些數字必須是逗號隔開的。屬性中固然能夠包含空格,可是空格不做爲分隔符。每一個數字定義了實線段的長度,分別是按照繪製、不繪製這個順序循環下去。須要注意兩個只與三個值的狀況
stroke-miterlimit 這個和canvas中的同樣,它處理何時畫和不畫線鏈接處的miter效果。
stroke-dashoffset 這個屬性設置開始畫虛線的位置
這個屬性使用設置的顏色填充圖形內部,使用很簡單,直接把顏色值賦給這個屬性就能夠了。 注意事項:
fill-opacity
,值的範圍是0到1。固然,你也能夠直接使用css來修改這些樣式
SVG和canvas中是同樣的,都是使用標準的HTML/CSS中的顏色表示方法,這些顏色均可以用於fill和stroke屬性。
基本有下面這些定義顏色的方式:
使用linearGradient元素便可定義線性漸變,每個漸變色成分使用stop
元素定義。
注意:
<defs>
標籤中offset屬性:這個和線性漸變的值是同樣,可是含義不同。在環形漸變中,0%表明圓心處,這個很好理解。
x1="0" x2="0" y1="0" y2="1":四個屬性決定漸變的方向
cx,cy,r屬性:其實也很好理解,環形漸變,固然要定義環的圓心和半徑了,體會一下上面例子中圓的大小和位置就能理解了。
fx,fy屬性:定義顏色中心(焦點)處的位置,也就是漸變色最濃處的座標
不過這裏須要注意一下上面cx,cy,r,fx,fy的值,你會發現它們都是小數,那麼單位是什麼呢?
這個須要先了解另一個相關的屬性:gradientUnits,它定義了定義漸變色使用的座標單位。這個屬性有2個可用值:userSpaceOnUse和objectBoundingBox。
objectBoundingBox是默認值,它使用的座標都是相對於對象包圍盒的(方形包圍盒,不是方形包圍盒的狀況比較複雜,略過),取值範圍是0到1。例如上例中的cx,cy的座標值(0.25,0.25)。意味着這個圓心是在包圍盒的左上角1/4處,半徑0.25意味着半徑長是對象方形包圍盒長的1/4,就像大家圖中看到的那樣。
userSpaceOnUse表示使用的是絕對座標,使用這個設置的時候,你必需要保證漸變色和填充的對象要保持在一個位置。
spreadMethod屬性:這個屬性定義了漸變色到達它的終點時應該採起的行爲。該屬性有3個可選值:pad(默認值),reflect,repeat
。pad不用說了,屬於天然過渡,漸變色結束之後,使用最後一個成員色直接渲染對象剩下的部分。refect會讓漸變色繼續,只不過漸變色會反向繼續渲染,從最後一個顏色開始到第一個顏色這個順序渲染;等到再次到達漸變色終點時,再反序,如此這般指導對象填充完畢。repeat也會讓漸變色繼續渲染,可是不會反序,仍是一遍一遍從第一種顏色到最後一種顏色渲染
例子看起來很簡單,由漸變色建立pattern
,而後使用pattern 填充矩形。這裏須要注意:
直接顯示在圖片中文本 -text元素 直接顯示文本可使用text元素
<svg>
<rect width="300" height="200" fill="red" />
<circle r="80" cx="150" cy="100" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
複製代碼
如上面的例子中所示,text元素能夠設置下列的屬性:
start,middle,end和inherit
三種值。除了這些屬性,下面的這些屬性都既能夠在CSS中指定,也能夠直接在屬性中指定:
**文本區間 - tspan元素 ** 這個元素是text元素的強力補充;它用於渲染一個區間內的文本;它只能出如今text元素或者tspan元素的子元素中。典型的用法就是強調顯示部分文本。例如:
<text>
<tspan font-weight="bold" fill="red">文字</tspan>
</text>
複製代碼
tspan元素能夠設置一下的屬性:
文本引用 - tref元素 這個元素容許引用定義過的文本,並高效的拷貝到當前位置,一般配合xlink:href
指定目的元素。由於是拷貝過來的,因此使用css修改當前文本的時候,不會修改原來的文本。
文本路徑 - textPatch元素 這個比較有意思,效果也很酷,能作出不少的藝術效果;這個元素從它的xlink:href屬性獲取指定的路徑並把文本對齊到這個路徑上
SVG存在兩套座標系統:視窗座標系與用戶座標系。默認狀況下,用戶座標系與視窗座標系的點是一一對應的,都爲原點在視窗的左上角,x軸水平向右,y軸豎直向下; SVG的視窗位置通常是由CSS指定,尺寸由SVG元素的屬性width和height設置
視窗:指的是網頁上面可視的矩形局域,長度和寬度都是有限的,這個區域通常與外圍對象的尺寸有關。
視窗座標系:本質是一個座標系,有原點,x軸與y軸;並且在兩個方向上是無限延伸的。默認狀況下,原點在視窗的左上角,x軸水平向右,y軸豎直向下。能夠對這個座標系的點進行變換。
用戶座標系:本質是一個座標系,有原點,x軸與y軸;並且在兩個方向上是無限延伸的。默認狀況下,原點在視窗的左上角,x軸水平向右,y軸豎直向下。能夠對這個座標系的點進行變換。
視窗空間變換由相關元素(這些元素建立了新的視窗)的屬性**viewBox
控制;用戶空間變換由圖形元素的transform
**屬性控制。視窗空間變換應用於對應的整個視窗,用戶空間變換應用於當前元素及其子元素。
viewBox屬性值的格式爲(x0,y0,u_width,u_height),每一個值之間用逗號或者空格隔開,它們共同肯定了視窗顯示的區域:視窗左上角座標設爲(x0,y0)、視窗的寬設爲u_width,高爲u_height;這個變換對整個視窗都起做用。
這個與css中的translate,rotate,skew,scale同樣。一樣能夠一塊兒使用
g元素是一種容器,它組合一組相關的圖形元素成爲一個總體;這樣,咱們就能夠對這個總體進行操做。這個元素一般能夠和desc和title元素配合使用,提供文檔的結構信息。結構良好的文檔一般可讀性和渲染效率都不錯。
注意幾點:
xmlns="www.w3.org/2000/svg"代表了整個svg元素默認的命名空間是svg。這個在無歧義的時候能夠省略。這裏因爲svg文檔是一個XML文檔,XML命名空間的相關規則這裏都是適用的。例如能夠給svg顯示的指定命名空間,給命名空間提供別名等。
g元素是能夠嵌套的。
組合起來的圖形元素就和單個的元素同樣,能夠給id值,這樣,須要的時候(例如動畫和重用一組元素)只用引用這個id值就能夠了。
組合一組圖形元素能夠統一設置這組元素的相關屬性(fill,stroke,transform等),這也是使用組合的一種場景。
兩個參數,若是沒有第二個參數,則默認賦值爲0。
一個參數,參數指旋轉的度數
每一個須要一角度以肯定元素斜切到多遠。
它須要兩個數字,做爲比率計算如何縮放。0.5表示收縮到50%。若是第二個數字被忽略了,它默認等於第一個值。
利用剛剛介紹的<g>
元素,把這些東西變成一個總體。能夠對總體進行操做
若是使用了變形,你會在元素內部創建了一個新的座標系統,應用了這些變形,你爲該元素和它的子元素指定的單位可能不是1:1像素映射。可是依然會根據這個變形進行歪曲、斜切、轉換、縮放操做。
SVG能夠嵌套SVG
clipPath:剪切。clipPath的這一部分區域纔會被顯示
mask:遮罩
opacity: fill-opacity: stroke-opacity: 固然,你可使用CSS樣式來修飾
使用xlink:href
插入圖片路徑 注意
: 若是你沒有設置x屬性或y屬性,它們自動被設置爲0。
若是你沒有設置height屬性或width屬性,它們自動被設置爲0。
若是width屬性或height等於0,將不會呈現這個圖像。
symbol元素用於定義圖形模板(模板能夠包含不少圖形),這個模板能夠被use元素實例化。模板的功能與g元素很類似,都是提供一組圖形對象,可是也有一些區別。與g元素不一樣的地方是:
1.symbol元素自己是不會被渲染的,只有symbol模板的實例會被渲染。
2.symbol元素能夠擁有屬性viewBox和preserveAspectRatio,這些容許symbol縮放圖形元素。
從渲染角度來講,與symbol元素類似的元素是marker(定義箭頭和標號)和pattern(定義顏色)元素;這些元素不會直接被渲染;他們的使用方式基本都是由use元素去實例化。正是這個緣由,對於symbol來講,'display'屬性是沒有意義的。
SVG容許定義一組對象,而後重用這組對象(注意,不只僅是圖形對象)。最多見的例子如定義漸變色,而後再其餘的圖形對象中賦給fill屬性。漸變色定義的時候是不會渲染的,因此這類型的對象能夠放到任何地方。重用對於圖形對象中也是常常存在的,並且咱們也不但願定義的時候直接渲染,而是想在引用的地方渲染,這個能夠用defs元素實現。
兩種使用:一種是使用fill填充。另外一個是使用use元素鏈接
任何svg, symbol, g, 單個的圖形元素和use元素本質上均可以做爲模板對象被use元素引用(例如初始化)。use引用的圖形內容會在指定的位置渲染。與image元素不一樣,use元素不能引用整個文檔。 use元素也有x, y, width和height屬性,這些屬性能夠省略,若是不省略的話,會將被引用的圖形內容座標或長度映射到當前的用戶座標空間來。
ns是什麼呢?就是 這個 "http://www.w3.org/2000/svg" tagName值 svg rect,circle等
SMIL是Synchronized Multimedia Integration Language(同步多媒體集成語言)的首字母縮寫簡稱
SMIL容許你作下面這些事情:
沿着運動路徑運動
set
意思設置,此元素沒有動畫效果。你可能會疑問了,既然這個元素沒有動畫效果,怎麼會是animation五大成員之一呢?
OK, 這樣的,雖然set雖然不能觸發連續的動畫,可是,其仍是能夠實現基本的延遲功能。就是指:能夠在特定時間以後修改某個屬性值(也能夠是CSS屬性值)。
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<g>
<text font-family="microsoft yahei" font-size="120" y="160" x="160">
馬
<set attributeName="x" attributeType="XML" to="60" begin="3s" />
</text>
</g>
</svg>
複製代碼
基礎動畫元素。實現單屬性的動畫過渡效果。
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<g>
<text font-family="microsoft yahei" font-size="120" y="160" x="160">
馬
<animate attributeName="x" from="160" to="60" begin="0s" dur="3s" repeatCount="indefinite" />
</text>
</g>
</svg>
複製代碼
一看就知道實現transform變換動畫效果的。知識是一脈相承的,這裏的transform變換與CSS3的transform變換
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<g>
<text font-family="microsoft yahei" font-size="80" y="100" x="100">馬</text>
<animateTransform attributeName="transform" begin="0s" dur="3s" type="scale" from="1" to="1.5" repeatCount="indefinite"/>
</g>
</svg>
複製代碼
animateMotion元素可讓SVG各類圖形沿着特定的path路徑運動
<svg width="360" height="200" xmlns="http://www.w3.org/2000/svg">
<text font-family="microsoft yahei" font-size="40" x="0" y="0" fill="#cd0000">馬
<animateMotion path="M10,80 q100,120 120,20 q140,-50 160,0" begin="0s" dur="3s" repeatCount="indefinite"/>
</text>
<path d="M10,80 q100,120 120,20 q140,-50 160,0" stroke="#cd0000" stroke-width="2" fill="none" />
</svg>
複製代碼
那麼疑問來了:「既然瀏覽器醬能夠本身判斷屬性類別,那這個屬性還有什麼意義嗎?」我琢磨着,可能某些屬性,XML能其做用,CSS也能其做用,例如font-size, 此時就須要明確下歸屬。
四個之間的約束
: a. 若是動畫的起始值與元素的默認值是同樣的,from參數能夠省略。 b. (不考慮values)to,by兩個參數至少須要有一個出現。不然動畫效果沒有。to表示絕對值,by表示相對值。拿位移距離,若是from是100, to值爲160則表示移動到160這個位置,可是,若是by值是160,則表示移動到100+160=260這個位置。 c. 若是to,by同時出現,則by打醬油,只識別to. d. 若是to,by,values都沒設置,天然沒動畫效果。若是任意(包括from)一個屬性的值不合法,規範上說是沒有動畫效果。可是,經測試,FireFox瀏覽器確實如此,可是Chrome特地作了寫容錯處理。例如,原本是數值的屬性,寫了個諸如a這個不合法的值,其會看成0來處理,動畫效果依然存在。 e. values能夠是一個值或多值。根據在Chrome瀏覽器下的測試,是一個值的時候是沒有動畫效果。多值時候有動畫效果。當values值設置並能識別時候,from, to, by的值都會被忽略。
那values屬性是幹什麼的呢?別看名字挺大衆的,其仍是有些功力的。咱們實現動畫,不可能就是單純的從a位置到b位置,有時候,須要去c位置過渡下。此時,實際上有3個動畫關鍵點。而from, to/by只能駕馭兩個,此時就是values大顯身手的時候了! 總結下,也就是from-to動畫、from-by動畫、to動畫、by動畫以及values動畫。
4. begin, end begin
的定義是分號分隔的一組值。看到沒?是一組值,單值只是其中的狀況之一。例如,beigin="3s;5s"表示的是3s以後動畫走一下,6s時候動畫再走一下(若是以前動畫沒走完,會當即中止從頭開始) 5. dur dur屬性值比begin簡單了好幾層樓,就後面兩種:常規時間值 | "indefinite".
「常規時間值」就是3s之類的正常值;"indefinite"指事件無限。試想下,動畫時間無限,實際上就是動畫壓根不執行的意思。所以,設置爲"indefinite"跟沒有dur是一個意思,與dur解析異常一個意思。
calcMode屬性支持4個值:discrete | linear | paced | spline. 中文意思分別是:「離散」|「線性」|「踏步」|「樣條」。
discrete from值直接跳到to值。
linear animateMotion元素之外元素的calcMode默認值。動畫從頭至尾的速率都是一致的。
paced 經過插值讓動畫的變化步調平穩均勻。僅支持線性數值區域內的值,這樣點之間「距離」的概念才能被計算(如position, width, height等)。若是」paced「指定,任何keyTimes或keySplines值都會打醬油。
spline 谷歌不兼容
插值定義貝塞爾曲線。spline點的定義在keyTimes屬性中,每一個時間間隔控制點由keySplines定義。
keyTimes = 「list」 跟上面提到的list相似,都是分號分隔一組值。keyTimes總名字上看是關鍵時間點的意思,大體就是這個意思。前面提到過values也是多值,這裏有一些約定的規則:首先,keyTimes值的數目要和values一致,若是是from/to/by動畫,keyTimes就必須有兩個值。而後對於linear和spline動畫,第一個數字要是0, 最後一個是1。 最後,每一個連續的時間值必須比它前面的值大或者相等。
paced模式下,keyTimes會被忽略;keyTimes定義錯誤,也會被忽略;dur爲indefinite也會被忽略。
keySplines = 「list」 keySplines表示的是與keyTimes相關聯的一組貝塞爾控制點(默認0 0 1 1)。每一個控制點使用4個浮點值表示:x1 y1 x2 y2. 只有模式是spline時候這個參數纔有用,也是分號分隔,值範圍0~1,老是比keyTimes少一個值。
若是keySplines值不合法或個數不對,是沒有動畫效果的。
repeatDur定義重複動畫的總時間。能夠是普通時間值或者」indefinite(」動畫循環到電腦死機)。
fill fill表示動畫間隙的填充方式。支持參數有:freeze | remove. 其中remove是默認值,表示動畫結束直接回到開始的地方。freeze「凍結」表示動畫結束後像是被凍住了,元素保持了動畫結束以後的狀態。
accumulate, additive accumulate是累積的意思。支持參數有:none | sum. 默認值是none. 若是值是sum表示動畫結束時候的位置做爲下次動畫的起始位置。
additive控制動畫是否附加。支持參數有:replace | sum. 默認值是replace. 若是值是sum表示動畫的基礎知識會附加到其餘低優先級的動畫上,
always是默認值,表示老是,也就是點一次圈圈,馬兒跑一下。whenNotActive表示動畫正在進行的時候,是不能重啓動畫的。never表示動畫是一波流。
// svg指當前svg DOM元素
// 暫停
svg.pauseAnimations();
// 重啓動
svg.unpauseAnimations()
複製代碼