成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

HTML 5中SVG 2D坐標與變換

開發 前端
SVG的視窗位置一般是由CSS指定,尺寸由SVG元素的屬性width和height設置,但是如果SVG是存儲在embedded對象中,而且包含SVG的文檔是用CSS或者XSL格式化的,此時會使用外圍對象的尺寸。

坐標系統

SVG存在兩套坐標系統:視窗坐標系與用戶坐標系。默認情況下,用戶坐標系與視窗坐標系的點是一一對應的,都為原點在視窗的左上角,x軸水平向右,y軸豎直向下;如下圖所示: 

SVG的視窗位置一般是由CSS指定,尺寸由SVG元素的屬性width和height設置,但是如果SVG是存儲在embedded對象中(例如object元素,或者其他SVG元素),而且包含SVG的文檔是用CSS或者XSL格式化的,并且這些外圍對象的CSS或者其他指定尺寸的值已經可以計算出視窗的尺寸了,則此時會使用外圍對象的尺寸。

這里需要區分視窗,視窗坐標系,用戶坐標系的概念:

視窗:指的是網頁上面可視的矩形局域,長度和寬度都是有限的,這個區域一般與外圍對象的尺寸有關。

視窗坐標系:本質是一個坐標系,有原點,x軸與y軸;而且在兩個方向上是無限延伸的。默認情況下,原點在視窗的左上角,x軸水平向右,y軸豎直向下。可以對這個坐標系的點進行變換。

用戶坐標系:本質是一個坐標系,有原點,x軸與y軸;而且在兩個方向上是無限延伸的。默認情況下,原點在視窗的左上角,x軸水平向右,y軸豎直向下。可以對這個坐標系的點進行變換。

默認情況下,視窗坐標系與用戶坐標系是重合的,但是這里需要注意,視窗坐標系屬于的是創建視窗的元素,視窗坐標系確定好以后,整個視窗的坐標基調就確定了。但是用戶坐標系是屬于每個圖形元素的,只要圖形進行了坐標變換,就會創建新的用戶坐標系,這個元素中所有的坐標和尺寸都使用這個新的用戶坐標系。

簡單點說:視窗坐標系描述了視窗中所有元素的初始坐標概況,用戶坐標系描述了每個元素的坐標概況,默認情況下,所有元素都使用默認的與視窗坐標系重合的那個用戶坐標系。

坐標空間變換

讓我們回顧一下canvas用戶坐標的變換,它們是通過平移,縮放,旋轉函數實現的;每次變換后對以后繪制的圖形都起作用,除非再次進行變換,這是"當前"用戶坐標系統的概念。canvas只有唯一一個用戶坐標系。

在SVG中,情況完全不同。SVG本身作為一種向量圖元素,它的兩個坐標系統本質上都可以算作"用戶坐標系統";SVG的兩個坐標空間都是可以變換的:視窗空間變換和用戶空間變換。視窗空間變換由相關元素(這些元素創建了新的視窗)的屬性viewBox控制;用戶空間變換由圖形元素的transform屬性控制。視窗空間變換應用于對應的整個視窗,用戶空間變換應用于當前元素及其子元素。

視窗變換 - viewBox屬性

所有的能建立一個視窗的元素(看下一節),再加上marker,pattern,view元素,都有一個viewBox屬性。

viewBox屬性值的格式為(x0,y0,u_width,u_height),每個值之間用逗號或者空格隔開,它們共同確定了視窗顯示的區域:視窗左上角坐標設為(x0,y0)、視窗的寬設為u_width,高為u_height;這個變換對整個視窗都起作用。

這里一定不要混淆:視窗的大小和位置已經由創建視窗的元素和外圍的元素共同確定了(例如最外層的svg元素建立的視窗由CSS,width和height確定),這里的viewBox其實是設置這個確定的區域能顯示視窗坐標系的哪個部分。

viewBox的設置其實是包含了視窗空間的縮放和平移兩種變換。

變換的計算也很簡單:以最外層的svg元素的視窗為例,假設svg的寬與長設置為width,height,viewBox的設置為(x0,y0,u_width,u_height)。則繪制的圖形,寬和高的縮放比例分別為:width/u_width, height/u_height。視窗的左上角的坐標設置為了(x0,y0)。

體會下面幾種代碼繪出的結果的不同:

  1. <svg width="200" height="200" viewBox="0 0 200 200"> 
  2.  <rect x="0" y="0" width="200" height="200" fill="Red" /> 
  3.  <rect x="0" y="0" width="100" height="100" fill="Green" /> 
  4. </svg> 

上面的例子繪制的圖中你可以看到綠色和紅色的矩形,這種情況下視窗坐標系的點還是與視窗上的點是一一對應的,這個也是默認情況。

  1. <svg width="200" height="200" viewBox="0 0 100 100"> 
  2.  <rect x="0" y="0" width="200" height="200" fill="Red" /> 
  3.  <rect x="0" y="0" width="100" height="100" fill="Green" /> 
  4. </svg> 

上面的例子繪制的圖中這個你只能看到綠色的矩形,而且綠色的矩形顯示在屏幕上是200*200像素的,這個時候坐標點已經不是一一對應了,圖被放大了。

  1. <svg width="200" height="200" viewBox="0 0 400 400"> 
  2.  <rect x="0" y="0" width="200" height="200" fill="Red" /> 
  3.  <rect x="0" y="0" width="100" height="100" fill="Green" /> 
  4. </svg> 

上面的例子繪制的圖中,視窗坐標系的單位被縮小,所以兩個矩形都縮小了。

在日常工作中,我們經常需要完成的一個任務就是縮放一組圖形,讓它適應它的父容器。我們可以通過設置viewBox屬性達到這個目的。

能建立新視窗的元素

任何時候,我們都可以嵌套視窗。創建新的視窗的時候,也會創建新的視窗坐標系和用戶坐標系,當然也包括裁減路徑也會創建新的。下列是能建立新視窗的元素列表:

svg:svg支持嵌套。

symbol:當被use元素實例化的時候創建新的視窗。

image:引用svg元素時會創建新視窗。

foreignObject:創建新視窗去渲染里面的對象。

保持縮放的比例 - preserveAspectRatio屬性

有些時候,特別是當使用viewBox的時候,我們期望圖形占據整個視窗,而不是兩個方向上按相同的比例縮放。而有些時候,我們卻是希望圖形兩個方向是按照固定的比例縮放的。使用屬性preserveAspectRatio就可以達到控制這個的目的。

這個屬性是所有能建立一個新視窗的元素,再加上image,marker,pattern,view元素都有的。而且preserveAspectRatio屬性只有在該元素設置了viewBox以后才會起作用。如果沒有設置viewBox,則preserveAspectRatio屬性會被忽略。

屬性的語法如下:preserveAspectRatio="[defer] <align> [<meetOrSlice>]"

注意3個參數之間需要使用空格隔開。

defer:可選參數,只對image元素有效,如果image元素中preserveAspectRatio屬性的值以"defer"開頭,則意味著image元素使用引用圖片的縮放比例,如果被引用的圖片沒有縮放比例,則忽略"defer"。所有其他的元素都忽略這個字符串。

align:該參數決定了統一縮放的對齊方式,可以取下列值:

none - 不強制統一縮放,這樣圖形能完整填充整個viewport。

xMinYMin - 強制統一縮放,并且把viewBox中設置的<min-x>和<min-y>對齊到viewport的最小X值和Y值處。

xMidYMin - 強制統一縮放,并且把vivewBox中X方向上的中點對齊到viewport的X方向中點處,簡言之就是X方向中點對齊,Y方向與上面相同。

xMaxYMin - 強制統一縮放,并且把viewBox中設置的<min-x> + <width>對齊到viewport的X值最大處。

類似的還有其他類型的值:xMinYMid,xMidYMid,xMaxYMid,xMinYMax,xMidYMax,xMaxYMax。這些組合的含義與上面的幾種情況類似。

meetOrSlice:可選參數,可以去下列值:

meet - 默認值,統一縮放圖形,讓圖形全部顯示在viewport中。

slice - 統一縮放圖形,讓圖形充滿viewport,超出的部分被剪裁掉。

下圖詮釋了各種填充的效果:


 

用戶坐標系的變換 - transform屬性

該類型變換是通過設置元素的transform屬性來指定的。這里需要注意,transform屬性設置的元素的變換,只影響該元素及其子元素,與別的元素無關,不影響別的元素。

平移 - translate

平移變換把相關的坐標值平移到指定的位置,該變換需要傳入兩個軸上平移的量。看例子:

  1. <rect x="0" y="0" width="10" height="10" transform="translate(30,40)" /> 

這個例子繪制一個矩形,并把它的起點(0,0)平移到(30,40)處。雖然可以直接設置(x,y)的坐標值,但是使用平移變換去實現也很方便。這個變換第二個參數可以省略,默認當0處理。

旋轉 - rotate

旋轉一個元素也是一個很常見的任務,我們可以使用rotate變換實現,該變換需要傳入旋轉的角度參數。看例子:

  1. <rect x="20" y="20" width="20" height="20" transform="rotate(45)" /> 

這個例子會顯示一個旋轉45度的矩形。有幾點注意:

1.這里的變換是以角度值為參數的。

2.旋轉指的是相對于x軸的旋轉。

3.旋轉是圍繞用戶坐標系的原點(0,0)展開的。

傾斜 - skew

transform還支持傾斜變換,可以是沿著x軸的(左右傾斜,正角度為向右傾斜,其實是傾斜了y軸),或者是沿著y軸的(上下傾斜,正角度為向下傾斜,其實是傾斜了x軸)傾斜;該變換需要傳入一個角度參數,這個角度參數會決定傾斜的角度。看下面的例子:

  1. <svg width="100" height="100"> 
  2.   <rect x="0" y="0" width="100" height="100" fill="green" /> 
  3.   <circle cx="15" cy="15" r="15" fill="red" /> 
  4.   <circle cx="15" cy="15" r="15" fill="yellow" transform="skewX(45)" /> 
  5.   <rect x="30" y="30" width="20" height="20"  /> 
  6.   <rect x="30" y="30" width="20" height="20" transform="skewX(45)"  /> 
  7.   <rect x="30" y="30" width="20" height="20" transform="skewY(45)"  /> 
  8. </svg> 

從結果中,你可以直接看到同樣尺寸的矩形,在不同的傾斜變換后,得到的位置和形狀。這里注意矩形的起始位置都已經改變了,這是因為在新的坐標系統中,(30,30)已經在不同的位置了。

縮放 - scale

縮放對象由縮放變換完成,該變換接受2個參數,分別指定在水平和豎直上的縮放比例,如果第二個參數省略則與第一個參數取相同的值。看下面的例子:

  1. <svg width="500" height="500"> 
  2.  <text x="20" y="20" font-size="20">ABC (scale)</text> 
  3.  <text x="50" y="50" font-size="20" transform="scale(1.5)">ABC (scale)</text> 
  4. </svg> 

變換矩陣 - matrix

學過圖形學的都知道,所有的變換其實都是由矩陣表征的,所以上面的變換其實都可以用一個3*3矩陣去表示:

  1. a c e  
  2. b d f  
  3. 0 0 1  

由于只有6個值用到了,所以也簡寫成[a b c d e f]。把matrix(a,b,c,d,e,f)賦給transfrom就可以實施相應的變換。變換會把坐標和長度都轉換成新的尺寸。上面各種變換對應的矩陣如下:

平移變換[1 0 1 0 tx ty]:

  1. 1 0 tx         
  2. 0 1 ty  
  3. 0 0 1  

縮放變換[sx 0 0 sy 0 0]:

  1. sx 0 0  
  2. 0 sy 0  
  3. 0  0 1  

旋轉變換[cos(a) sin(a) -sin(a) cos(a) 0 0]:

  1. cos(a) -sin(a) 0  
  2. sin(a) cos(a)  0  
  3.   0      0     1  

沿X軸的傾斜[1 0 tan(a) 1 0 0]:

  1. 1 tan(a) 0  
  2. 0   1    0  
  3. 0   0    1  

沿Y軸的傾斜[1 tan(a) 0 1 0 0]:

  1. 1      1 0  
  2. tan(a) 1 0  
  3. 0      0 1  

變換本質

前面我們總結canvas的時候,我們知道各種變換都是作用在用戶坐標系上的。在SVG中,所有的變換也都是針對兩個坐標系(本質上都是"用戶坐標系")的。當給容器對象或圖形對象指定"transform"屬性,或者給"svg,symbol,marker,pattern,view"指定"viewBox"屬性以后,SVG會根據當前的用戶坐標系統進行變換,去創建新的用戶坐標系,并作用于當前的對象以及它的子對象。該對象中指定的坐標和長度的單位不再是1:1的對應到外圍的坐標系,而是隨著變形,轉換到新的用戶坐標系中;這個新的用戶坐標系是只作用于當前的元素及其子元素。

變換鏈

transform屬性支持設置多個變換,這些變換只要中間用空格分開,然后一起放到屬性中就可以了。執行效果跟按順序獨立執行這些變換是一樣的。

  1. <g transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)"> 
  2.   <!-- graphics elements go here --> 
  3. </g> 

上面的效果與下面的一樣:

  1. <g transform="translate(-10,-20)"> 
  2.   <g transform="scale(2)"> 
  3.     <g transform="rotate(45)"> 
  4.       <g transform="translate(5,10)"> 
  5.         <!-- graphics elements go here --> 
  6.       </g> 
  7.     </g> 
  8.   </g> 
  9. </g> 

單位

最后說一下單位,任何坐標和長度都可以帶和不帶單位。

不帶單位的情況

不帶單位的值被認為帶的是"用戶單位",就是當前用戶坐標系的單位值。

帶單位的情況

svg中相關單位與CSS中是一樣的:em,ex,px,pt,pc,cm,mm和in。長度還可以使用"%"。

相對度量單位:em和ex也與CSS中一樣,是相對于當前字體的font-size和x-height來說的。

絕對度量單位:一個px是等于一個"用戶單位"的,也就是"5px"與"5"是一樣的。但是一個px是不是對應一個像素,那就看有沒有進行過一些變換了。

其他的幾個單位基本都是px的倍數:1pt=1.25px,1pc=15px,1mm=3.543307px,1cm=35.43307px,1in=90px。

如果最外層的SVG元素的width和height沒有指定單位(也就是"用戶單位"),則這些值會被認為單位是px。

這一篇比較拗口,其實只要記住“圖形元素的坐標和長度指的是,經過視窗坐標系變換和用戶坐標系變換雙重變換后,新用戶坐標系的坐標和長度”就可以了。

實用參考:

腳本索引:http://msdn.microsoft.com/zh-cn/library/ff971910(v=vs.85).aspx

開發中心:https://developer.mozilla.org/en/SVG

熱門參考:http://www.chinasvg.com/

官方文檔:http://www.w3.org/TR/SVG11/

原文地址:http://www.cnblogs.com/dxy1982/archive/2012/05/07/2395732.html

【編輯推薦】

責任編輯:張偉 來源: 沙場秋點兵的博客
相關推薦

2012-05-07 15:08:00

HTML5

2012-05-07 16:14:21

HTML5

2012-05-07 14:25:16

HTML5

2012-05-07 14:13:59

HTML5

2012-05-08 09:53:56

HTML 5

2013-01-08 11:00:20

IBMdW

2012-11-07 09:43:58

IBMdw

2011-06-24 17:38:09

Qt 坐標 事件

2011-04-25 14:36:24

Ubuntu Unit

2013-01-30 16:15:40

adobeHTML5css3

2011-08-11 18:07:55

iPhoneQuratz 2D

2023-05-03 09:01:41

CanvasWebGL

2011-08-08 17:17:55

Cocos2D 坐標 OpenglES

2020-10-26 13:40:00

CascadingSt

2013-05-22 15:49:46

2022-05-23 10:26:10

人工智能機器學習機器視覺

2012-12-24 09:11:58

iOSUnity3D

2011-12-29 14:22:40

Java

2015-10-23 13:44:14

巴巴獵

2024-04-23 09:30:07

3D模型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 四虎影院新网址 | 亚洲精色 | 户外露出一区二区三区 | 亚洲成人天堂 | 国产精品99久久久久久动医院 | 久久久女女女女999久久 | 国产成人免费在线 | 国产91av视频 | 一区二区三区日 | 中文字幕成人av | 91网站在线看 | 黄色毛片一级 | 成人在线小视频 | 免费国产一区 | 91观看 | 91久久夜色 | 91麻豆精品国产91久久久久久 | 亚洲福利在线观看 | 久久精品国产一区二区 | 久久视频精品 | 综合久久久久久久 | 精品婷婷 | 盗摄精品av一区二区三区 | 毛片网在线观看 | 亚洲精品欧美 | 99久久婷婷国产综合精品 | 亚洲97 | 久久精品日产第一区二区三区 | 亚洲91av| 天天干天天草 | 国产精品区二区三区日本 | 成人免费网站 | 别c我啊嗯国产av一毛片 | 人人99| 国产不卡一区在线观看 | 天堂一区 | 奇米影视77 | 人妖一区 | 精品美女| 国产一区二区黑人欧美xxxx | 国产乱码精品一区二区三区中文 |