自動選擇SVG和VML的WEB頁面

自動選擇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("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("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_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("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混合時儘可能避免使用,實在不行就只能使用腳本模擬實現了。
l         SVG爲獨立的嵌入對象,所以要使用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方式是比較好的一種模式。
相關文章
相關標籤/搜索