SVG指令碼編程簡介
本文主要介紹SVG的指令碼編程,並分別給出放大、縮小,查詢,滑鼠事件等執行個體。
一、 SVG簡介
SVG,全稱為Scalable Vector Graphics(可伸縮向量圖形)。它是W3C制定的、用向量描述圖形的XML應用標準。它有著許多的優點,比如可擴充性(scalable),動態,互動性強。SVG支援無極放大,對SVG圖片進行任意比例的放大都不會損害圖片的顯示(沒有太多的失真),其他諸如BMP,JPEG格式的圖片都不支援無級放大。SVG有動畫元素,只要在SVG檔案中嵌入SVG動畫元素就可以實現動畫效果了。同時 SVG也定義了豐富的事件,包括滑鼠事件和鍵盤事件,只要對SVG進行相關的指令碼編程就可以實現SVG檔案的互動操作。
SVG帶有許多基本的圖形元素,只要通過組合基本圖形元素就可以構建出SVG檔案。
二、 SVG指令碼編程
在SVG中,可以通過指令碼編程來實現一些比較複雜的互動操作。SVG用<script>元素來在SVG文檔中插入指令碼,它的功能幾乎和HTML中的<script>標記一樣。其一般格式為:
<script type=”text/javascript”>
<![CDATA[
<!—這裡插入指令碼程式段-->
]]>
</script>
<script>有兩個屬性,type=”content-type”,這裡指明所用的script語言的類型。預設情況下script採用的語言是javascript語言。Xlink:href="/blog/”<";uri>”指明引用外部指令檔的url。下面的例子示範了SVG中的滑鼠事件。
<svg width="400" height="200">
<script><![CDATA[
function showmsg()
{
alert("you had clicked the green rect");
}
]]></script>
<g id="rect1">
<rect id="rectangle" onclick="showmsg()" x="50" y="50" width="100" height="50" style="fill:green"/></g>
</svg>
在文本中輸入上面代碼,用IE開啟,然後用滑鼠點擊綠色的矩形,將會提示“你點擊了矩形”的資訊。
所以如果要實現對SVG的指令碼編程,只需要在相關的元素上增加事件處理函數(onclick="showmsg()"),然後在<script>標記中實現相關函數就可以了。
另外時間處理函數的實現除可以放在SVG的<script>標記中外,也可以放在SVG嵌入的父HTML檔案中,這樣的話也可以方便的實現SVG和HTML的資料交換。例如下面的例子。
Svg檔案:1.svg
<svg width="400" height="200">
<g id="rect1">
<rect id="rectangle" onclick="showmsg()" x="50" y="50" width="100" height="50" style="fill:green"/></g>
</svg>
HTML檔案:a.html
<html><head><title>SVG事件</title>
<script language=javascript>
<!—
function showmsg()
{
Alert("you had clicked the green rect ");
}
//-->
</script>
<body >
<embed name="id1" pluginspage=”http://www.adobe.com/svg/viewer/install/” align="top" src="/blog/1.svg" height="200px" width="200px" type="image/svg+xml">
</body>
</html>
當你開啟a.html檔案後,你會發現效果跟上面的例子一樣。
SVG支援的事件有很多,比較常用的有onclick,onmousedown,onmouseup,onmouseout,onmousemove,onload等等。更多的事件請查看:
三、 指令碼編程應用執行個體
本部分將通過幾個執行個體來分析指令碼程式在SVG中的應用。
1、滑鼠事件(示範滑鼠事件的使用方法,以及常用的事件)
請看下面的例子:
<svg width="400" height="200">
<script><![CDATA[
function mout()
{
alert("you are out");
}
]]></script>
<g id="rect1">
<rect id="rectangle1" onmouseout="mout()" x="50" y="50" width="150" height="150" style="fill:red"/>
</g>
</svg>
用IE開啟上面的SVG檔案,當你的滑鼠移開紅色的矩形框的時候,將會彈出提示資訊"you are out"。
下面給出常見的滑鼠事件和其觸發條件。
onmouseout
當滑鼠移開一個物體(element)的時候觸發該事件
onmousedown
當在一個物體(element)上按下滑鼠鍵時觸發該事件
onmouseup
當在一個物體(element)上鬆開滑鼠鍵時觸發該事件
onmousemove
當滑鼠在一個物體(element)上移動時觸發該事件
onclick
當滑鼠點擊物體(element)的時候將觸發該事件
更多的事件請參看http://www.w3.org/TR/SVG/interact.html。
對滑鼠事件需要注意的是有時候可能同時有幾個事件同時發生,我們可以通過實驗得出響應事件的執行順序。
2、放大、縮小(示範指令碼語言對SVG中相關元素的屬性控制)
SVG的瀏覽器外掛程式帶有放大、縮小的功能,但是在實際的應用中,我們需要自己編程實現SVG圖象檔案的放大、縮小。下面的例子通過SVG的更改viewbox屬性來實現放大、縮小功能。(處理函數放在父HTML檔案中)
SVG檔案:1.svg
<svg viewBox="0 0 400 200" id="mainview">
<g>
<text id="texte" x="200" y="100" style="text-anchor:middle;font-size:25;font-family:Arial;fill:red">haha ,here!</text>
</g>
</svg>
HTML檔案:aa.html
<html><head><title>SVG事件</title>
<body >
<script language="javascript" >
function fda()
{
var SvgMainMapDoc=id1.getSVGDocument();
var OverMapview=SvgMainMapDoc.getElementById("mainview");
OverMapview.setAttribute("viewBox","100 50 200 100");
}
function sxiao()
{
var SvgMainMapDoc=id1.getSVGDocument();
var OverMapview=SvgMainMapDoc.getElementById("mainview");
OverMapview.setAttribute("viewBox","-200 -100 800 400");
}
</script>
<embed name="id1" pluginspage=http://www.adobe.com/svg/viewer/install/ align="top" src="/blog/1.svg" height="200px" width="400px" type="image/svg+xml">
<input type="button" value="放大" name="fda" onclick="fda()">
<input type="button" value="縮小" name="sxiao" onclick="sxiao()">
</body>
</html>
用IE開啟aa.html,按下放大,縮小按鈕將可以看到放大、縮小的效果。HTML中通過getSVGDocument()擷取SVG文檔的 DOM(文件物件模型),然後再通過getElementById和ID來擷取element的指標,然後通過setAttribute來設定 element(即本例中ID為mainview的svg元素)。上面用到的幾個函數都是DOM函數,更多的DOM函數及介紹可以在http://pilat.free.fr/routines/js_dom.htm上獲得。
下面介紹一下通過viewbox放大、縮小的原理。Viewbox中有四個數字,分別表示最小的x座標,y座標,最大x座標和最小x座標之差,最大 y座標和最小y座標之差。也就是說viewbox表示的是當前的顯示範圍,因此只要改變viewbox的值就可以實現SVG圖象的放大和縮小。
3、屬性查詢、高亮顯示
屬性查詢在現實中有著許多的應用,通過查詢可以得出我們感興趣的東西。下面介紹如果實現對SVG屬性的查詢。
SVG檔案:1.svg
<svg viewBox="0 0 400 400" id="mainview">
<g id="id1">
<rect id="rectangle" name="a1" x="0" y="0" width="50" height="50" style="fill:green"/>
<rect id="rectangle1" name="a2" x="50" y="50" width="50" height="50" style="fill:green"/>
<rect id="rectangle2" name="a3" x="100" y="100" width="50" height="50" style="fill:green"/>
<rect id="rectangle3" name="a4" x="150" y="150" width="50" height="50" style="fill:green"/>
<rect id="rectangle4" name="a5" x="200" y="200" width="50" height="50" style="fill:green"/>
<rect id="rectangle5" name="a6" x="250" y="250" width="50" height="50" style="fill:green"/>
<rect id="rectangle6" name="a7" x="300" y="300" width="50" height="50" style="fill:green"/>
<rect id="rectangle7" name="a1" x="350" y="350" width="50" height="50" style="fill:green"/>
</g>
</svg>
HTML檔案:aa.html
<html><head><title>查詢SVG屬性</title>
<body >
<script language="javascript" >
function search(searchvalue)
{
var SvgMainMapDoc=id1.getSVGDocument();
SvgObj=SvgMainMapDoc.getElementById('g1');
SvgObj1=SvgObj.getChildNodes;
for(iCount=1;iCount<((SvgObj1.length)-1);iCount+=2)
{
if(SvgObj1.item(iCount).getAttribute("name")==searchvalue)
{
SvgStyle1=SvgObj1.item(iCount).getStyle();
SvgStyle1.setProperty('fill','green');
}
}
}
function clearaa()
{
var SvgMainMapDoc=id1.getSVGDocument();
SvgObj=SvgMainMapDoc.getElementById('g1');
SvgObj1=SvgObj.getChildNodes;
for(iCount=1;iCount<((SvgObj1.length)-1);iCount+=2)
{
SvgStyle1=SvgObj1.item(iCount).getStyle();
SvgStyle1.setProperty('fill','red');
}
}
</script>
<embed name="id1" pluginspage="http://www.adobe.com/svg/viewer/install/" align="top" src="/blog/1.svg" height="200px" width="400px" type="image/svg+xml">
<form name="searchvalue">
<input name="value1" size="12"><input type="button" value="查詢" name="search1" onclick="search(this.form.value1.value)">
<input type="button" value="清除" name="clear" onclick="clearaa()">
</form>
</body>
</html>
用IE開啟aa.html,輸入查詢的值如”a1”,選取查詢將可以看到有兩個矩形高亮顯示,這是查詢的結果。清除可以消除高亮顯示。
下面分析一下查詢的過程。通過getSVGDocument()擷取SVG文檔的DOM(文件物件模型),然後再通過getElementById 和ID(”id1”)來擷取element的指標,再通過getChildNodes來獲得其子節點,最後通過item(序號)來訪問其子節點,並逐個判斷其name屬性的值是否跟要查詢的值相同,從而決定是否高亮顯示。這裡需要注意的是子節點的序號是從1開始,並且以2遞增的。