1. 程式人生 > >Web圖形開發,選擇SVG還是VML

Web圖形開發,選擇SVG還是VML

自動選擇SVGVMLWEB頁面 問題 在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方式是比較好的一種模式。