Web圖形開發,選擇SVG還是VML
阿新 • • 發佈:2019-02-14
自動選擇SVG和VML的WEB頁面
問題
在WEB上使用二維圖形程式設計的人員現在面臨者一個兩難的選擇,是使用SVG,還是VML?二者的功能
相似,可以滿足大多數WEB二維圖形應用的需求,但目前的情況是:VML只能在IE中使用,SVG被firefox,opera等瀏覽器的最新版本支援, 並且是W3C制定的開放標準,但目前IE不內建支援SVG,只能通過ADOBE的SVG外掛顯示。
對於有特定使用者的應用,可能選擇哪一種技術都可以,軟體提供方可以要求使用者安裝和配置 所需的環境。但對於面向INTERNET使用者的應用,例如網上地圖等,這個問題就比較明顯了。IE無疑是最廣泛使用的瀏覽器,而且大多數使用者在不瞭解網站 內容的情況下,不會選擇下載並安裝一個4M多的SVG外掛。而在技術上,SVG無疑前景更光明,而且被其它瀏覽器支援,可以被非WINDOWS平臺使用者使 用。
思路
能否通過使用者瀏覽器的型別,自動在SVG和VML之間切換,以在瀏覽器上顯示同樣(或基本相似)的圖形?(下面提到的SVG都是SVG1.1標準)
解決方法
1, 根據使用者瀏覽器情況,設定顯示標誌
//設定使用SVG顯示標誌,預設為使用
var useSVG = true;
//如果為IE則使用VML
if (navigator.appName == "Microsoft Internet Explorer")
useSVG
= false;
//如果為其它瀏覽器,則使用SVG,這裡用Opera
if
(navigator.userAgent.search("Opera")>=0)
useSVG
= true;
2, 在HTML初始化時,載入SVG或VML物件
if(useSVG)
{
var
elem = document_createElement_x_x_x_x_x("embed");
elem.id
= "svgCanvas";
elem.width
= 500;
elem.height
= 500;
elem.name
= "svgCanvas";
elem.src
= "canvas.svg";
elem.wmode
= "transparent";
elem.type
= "image/svg+xml";
document.body.insertBefore(elem,null);
}
else
{
var
elem = document_createElement_x_x_x_x_x("v:group");
elem.id
= "vmlCanvas";
elem.style.width
= 500 + "px";
elem.style.height
= 500 + "px";
elem.coordsize
= "200,200";
document.body.insertBefore(elem,null);
}
之後,我們就可以分別在SVG或VML畫布上進行操作了。當然最好是定義一個與顯示無關的圖形物件。
3, 圖形物件,此處為一個簡單的圓
function Bubble(id, cx, cy, r, stroke, fill)
{
this.id
= id;
this.cx =
cx;
this.cy
= cy;
this.r
= r;
this.stroke
= stroke;
this.fill
= fill;
this.draw
= draw;
this.move
= move;
}
其顯示和移動實現為:
function draw()
{
if(useSVG)
{
//alert("svg");
var
svgDocument = GetSvgDocument();
if(svgDocument
== null)
return;
var
elem = svgdocument_createElement_x_x_x_x_xNS(svgns, "circle" );
elem.setAttributeNS(null,
"id", this.id);
elem.setAttributeNS(null,
"cx", this.cx);
elem.setAttributeNS(null,
"cy", this.cy);
elem.setAttributeNS(null,
"r", this.r);
elem.setAttributeNS(null,"stroke",this.stroke);
elem.setAttributeNS(null,"fill",this.fill);
var
svgCanvas = GetSvgCanvas();
if(svgCanvas
== null)
return;
svgCanvas.a(elem);
}
else
{
//alert("vml");
var
elem = document_createElement_x_x_x_x_x("v:oval");
with
(elem.style)
{
position="absolute";
top=this.cy
- this.r;
left=this.cx
- this.r;
width=parseInt(this.r*2);
height=parseInt(this.r*2);
}
elem.coordorigin
= "0,0";
elem.strokecolor=this.stroke;
elem.FillColor
= this.fill;
vmlCanvas.insertBefore(elem,null);
}
}
function
move(x, y)
{
this.cx
= x;
this.cy
= y;
}
4, 使用
var bubble1 = new Bubble("b1", 100, 100, 30, "purple", "green");
bubble1.draw();
var
bubble2 = new Bubble("b2", 30, 20, 20, "red", "yellow");
bubble2.draw();
VML顯示:
SVG顯示
5,注意事項:
l通過上面的圖可以看出,儘管比較相似,但還是有所不同,例如圓的邊線由於使用的是預設屬性,SVG和VML使用的筆畫粗細是不同。因此要顯示完全相同的圖形要付出很大的工作量。
l儘管SVG和VML在大多數情況下可以互相替換,但還是有一些對方不支援的特性和屬性。例如SVG中的動畫(animate)等,這些要在VML-SVG混合時儘量避免使用,實在不行就只能使用指令碼模擬實現了。
lSVG為獨立的嵌入物件,因此要使用embedded列表取得,而VML可以直接使用HTML的文件物件。在SVG動態嵌入時,要判斷載入情況,在載入完成後才可以操作。
在SVG中載入事件中通知HTML
function OnLoadEvent(evt)
{
window.parent.svgLoadFlag
= true;
}
在HTML初始化時,等待SVG載入完成標誌
if(useSVG)
{
//Wait
svg load event
if
( svgLoadFlag == false )
{
setTimeout("renderObjects()",100);
return;
}
}
l如果使用互動事件,例如滑鼠操作等,SVG和VML的事件物件結構是不同的,傳遞方式也不相同,應分別處理,不過一般在得到事件物件的屬性,例如座標位置,產生事件物件ID後,就可以使用相同的處理函數了。例如:
//SVG的事件處理
function svgClick(evt)
{
var
choiceId = evt.target.getAttributeNS(null,"id");
selectChoice(choiceId);
}
function
vmlClick()
{
var choiceId = event.srcElement.name;
selectChoice(choiceId);
}
因此在VML/SVG混合程式設計時,採用MODEL-VIEW-CONTROL方式是比較好的一種模式。