SVG transform用法詳解

admin發表於2017-07-27

建議在閱讀本章章節之後,再閱讀SVG transform座標變化深入理解一章節加深理解。

一.css3的transform屬性和SVG元素的transform屬性:

使用SVG元素的transform屬性可以實現變換效果,看如下程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
svg {
  border:1px solid red
}
</style>
</head>
<body>
<svg>
  <rect x="20" y="20"
        width="100"
        height="100"
        fill="blue"
        transform="rotate(10)"
        />
</svg>                        
</body>
</html>

矩形選旋轉一定的角度;css3也具有transform屬性,那麼此屬效能不能實現SVG元素的變換功能呢。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
* {
  margin:0px;
  padding:0px;
}
svg {
  border:1px solid red;
  width:300px;
  height:300px;
  margin:100px;
}
#ant {
  transform:rotate(10deg)
}
</style>
</head>
<body>
<svg>
  <rect id="ant"
         x="60" y="60"
        width="100"
        height="100"
        fill="blue"/>
  <rect
        x="60" y="60"
        width="120"
        height="120"
        fill="red"
        fill-opacity="0.3"
        transform="rotate(10)" />
</svg>                       
</body>
</html>

css3的transform屬性也可實現,但IE瀏覽器和edge瀏覽器不支援。

巨大的差別:

css3的transform屬性對普通HTML元素進行變換的時候,座標原點(0,0)預設是元素的中心;css3的transform和SVG元素的transform屬性對SVG元素進行變換的時候,原點是當前所在使用者座標系的原點,而不是元素的中心。程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
* {
  margin:0px;
  padding:0px;
}
svg {
  border:1px solid red;
  width:300px;
  height:300px;
  margin:100px;
}
#ant {
  transform:rotate(25deg)
}
div {
  position:absolute;
  left:160px;
  top:160px;
  width:100px;
  height:100px;
  background-color:red;
  opacity:0.3;
  transform:rotate(25deg)
}
</style>
</head>
<body>
<svg>
  <rect id="ant"
         x="60" y="60"
        width="100"
        height="100"
        fill="blue"/>
</svg>
<div></div>                         
</body>
</html>

旋轉之後出現明顯的差異,因為div以自身中心為原點旋轉,而svg元素是圍繞它所在的當前使用者座標系原點旋轉。至此,介紹了css3的變換和SVG元素自帶變換屬性的一些關聯和區別,下面具體介紹一下SVG圖形變換知識。

二.translate位移:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
* {
  margin:0px;
  padding:0px;
}
svg {
  border:1px solid red;
  width:300px;
  height:300px;
  margin:100px;
}
div {
  position:absolute;
  left:160px;
  top:160px;
  width:120px;
  height:120px;
  background-color:red;
  opacity:0.3;
  transform:translate(50px,50px)
}
</style>
</head>
<body>
<svg>
  <rect id="ant"
         x="60" y="60"
        width="100"
        height="100"
        transform="translate(50,50)"
        fill="blue"/>
</svg>
<div></div>                         
</body>
</html>

div和svg在垂直和水平方向都移動50px,最終座標是重合的,但兩者是有一點差別。

看如下圖示:

1485876084300930.png

(1).區別是,兩元素的座標原點是不同,一個在元素中心,一個在使用者座標系原點(預設左上角)。

(2).實質是相同的,每一次變換都會建立一個新的座標系,實質是對這個新座標系在原來座標系基礎上的位移。

其他區別:

css3的transform屬性可以使用如下形式:

[CSS] 純文字檢視 複製程式碼
translateX(tx)
translateY(ty)
translate(tx[, ty])
translateZ(tz)

但是SVG元素的transform屬性只支援如下形式:

[XML] 純文字檢視 複製程式碼
translate(tx[ ty])

並且SVG元素的transform屬性是不能夠帶單位的;多個引數的話,即可使用空格分隔也可以使用逗號分隔。

與CSS3的transform屬性相同,SVG元素translate位移也支援多宣告累加:

[XML] 純文字檢視 複製程式碼
transform="translate(10 20) translate(5 10)"

等同於如下:

[XML] 純文字檢視 複製程式碼
transform="translate(15 30)"

三.rotate旋轉:

旋轉在文章的開頭部分已經有所涉及,看圖示如下:

1485876229519465.png

特別說明:用紅線標識的是旋轉之前座標系的x軸和y軸。

(1).左側是對普通HTML元素的旋轉,元素的中心就是座標系的原點(0,0)。

(2).右側是對SVG元素的旋轉,圍繞的是所在的當前使用者座標的原點。

再強調一遍:每一次變換,都會建立一個新的座標系。

css3的rotate旋轉可以有如下形式:

[CSS] 純文字檢視 複製程式碼
rotate3d(x,y,z,angle)
rotateX(angle)
rotateY(angle)
rotateZ(angle)

angle必須要有單位,例如deg(度), turn(圈), grad,也可以使用calc()計算。

但是SVG元素的rotate只有一種形式:

[XML] 純文字檢視 複製程式碼
rotate(angle[ x y])

並且角度不能帶有單位;除去角度之外,還有一個可選的引數,它用來規定旋轉圍繞的座標(它純粹規定旋轉圍繞的中心點,並沒有對當前座標系的原點有任何改變)。程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style>
* {
  margin:0px;
  padding:0px;
}
svg {
  border:1px solid red;
  width:300px;
  height:300px;
  margin:100px;
}
</style>
</head>
<body>
<svg>
  <rect id="ant"
         x="60" y="60"
        width="100"
        height="100"
        transform="rotate(45 110 110)"
        fill="blue"/>
  <rect id="ant"
        x="60" y="60"
        width="100"
        height="100"
        fill-opacity="0.5"
        fill="red" />
</svg>
<div></div>                         
</body>
</html>

通過roate()的第二個引數將旋轉中心移動到了元素的中心點。

前面已經提到過,第二個引數純粹規定旋轉圍繞的中心點,並沒有對當前座標系的原點有任何改變,所以後面追加的旋轉不能共享這個旋轉中心,看如下程式碼:

[XML] 純文字檢視 複製程式碼
transform="rotate(45 110 110) rotate(-45)"

第一個旋轉圍繞是座標(110,110),但是第二個旋轉是圍繞的當前元素所在的座標系原點。

四.scale縮放:

css3的scale縮放具有以下語法形式:

[CSS] 純文字檢視 複製程式碼
scale3d(x,y,z)
scaleX(x)
scaleY(y)
rotateZ(z)

SVG元素的scale支援如下形式:

[XML] 純文字檢視 複製程式碼
scale(sx[, sy])

如果第二個引數省略,那麼y軸縮放與x軸縮放相同。

圖示如下:

1485876426760750.png

有沒有發現,不但元素的尺寸產生了縮放,而且座標也產生了縮放。

這非常的好解釋,因為每次變換都會產生一個新的座標系,這個新座標系整個進行了縮放。

五.skew斜切:

如果僅看一個方向的斜切,就如同將一個矩形在一個方向上進行拉伸(總面積不變),以x軸斜切為例子:

1485876465394162.jpg

在前面的變換中,都是支援scale(sx[, sy])類似語法形式,但是skew卻反其道而行之,只能夠分開寫:

[XML] 純文字檢視 複製程式碼
skewX()
skewY()

說明:每一次變換都會建立一個新的座標系,變換是對整個座標系的變換,所以導致視覺上元素髮生了變換。

圖示如下:

1485876515644387.png

圖片是css3對普通元素的斜切和svg元素自身屬性斜切的差別,這也是由於座標系原點的不同導致的。

skewX(α1) skewX(α2)和skewX(α1 + α2)最終變換效果不同,因為斜切角度和元素偏移大小非簡單的線性變化。

特別說明:本文基本翻譯於https://css-tricks.com/transforms-on-svg-elements/,但是經過了自己總結。

相關文章