解決html5 + js開發APP無法顯示SVG問題(轉化成canvas)


  項目里用到了kendo UI DataViz的折線圖、餅狀圖等去顯示一些統計信息,這些圖的顯示用到了SVG。

  現在最新的Chrome、Safari、Moz都支持了SVG標簽,甚至是iPhone里的Safari都支持了SVG。

  但是Android要到3.0版本及以上才支持SVG,如果不是3.0及更高版本,用戶必須升級瀏覽器內核才能顯示。

  這里有個解決方案,可以將SVG轉換為canvas再顯示。用到了由google提供的canvg-1.2庫。

 

  具體解決方案實例:

  首先探測瀏覽器是否支持SVG,這里借鑒了modernizr的判斷方法。如果支持,這個函數返回true,反之false:

function testSVG(){
    var ns = {'svg': 'http://www.w3.org/2000/svg'};
    return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
}

 

  做出判斷之后,就能動態的加載圖像,如果支持SVG,直接用SVG標簽就OK,反之就需要將SVG的標簽轉換為canvas再顯示。

  SVG轉化成canvas就要用到canvg,可以到http://code.google.com/p/canvg/去下載,也能連接到google的服務器上:

  

<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script> 

 

 

  使用方法有兩種(google網站上寫着的):

<script type="text/javascript">
window.load = function() {
  //load '../path/to/your.svg' in the canvas with id = 'canvas'
  canvg('canvas', '../path/to/your.svg')

  //load a svg snippet in the canvas with id = 'drawingArea'
  canvg(document.getElementById('drawingArea'), '<svg>...</svg>')

  //ignore mouse events and animation
  canvg('canvas', 'file.svg', { ignoreMouse: true, ignoreAnimation: true }) 
}
</script>

 

  這里我用到了第二種方法,也就是將svg標簽的html字符串轉化成canvas。

 

  首先要得到kendo UI Dataviz繪制的SVG圖形的整個SVG標簽的html。再將這個SVG標簽的html放入canvg函數即可。

  具體參照下面的demo,先用kendoChart繪制SVG圖形,再判斷瀏覽器是否支持SVG,如果不支持,得到SVG標簽的整個html,再用canvg轉換。(chart的數據是用kendo UI chart的demo的數據)

  

  html:

  

<div id="chart"></div>

 

  

  js(依賴jquery):

//create chart
                    $("#chart").kendoChart({
                        theme: $(document).data("kendoSkin") || "default",
                        title: {
                            text: "Break-up of Spain Electricity Production for 2008"
                        },
                        legend: {
                            position: "bottom",
                            labels: {
                                template: "#= text # (#= value #%)"
                            }
                        },
                        seriesDefaults: {
                            labels: {
                                visible: true,
                                format: "{0}%"
                            }
                        },
                        series: [{
                            type: "pie",
                            data: [ {
                                category: "Hydro",
                                value: 22
                            }, {
                                category: "Solar",
                                value: 2
                            }, {
                                category: "Nuclear",
                                value: 49
                            }, {
                                category: "Wind",
                                value: 27
                            } ]
                        }],
                        tooltip: {
                            visible: true,
                            format: "{0}%"
                        }
                    });
                
                //判斷是否支持SVG
                /*
                    if(!testSVG()){
                        var svgTagHtml = $("#chart").data("kendoChart").svg();
                      var canvasHtml = '<canvas id="kendoChart_canvas"></canvas>';
                      $("#chart").empty().html(canvasHtml);
                      canvg(document.getElementById('kendoChart_canvas'), svgTagHtml);
                    }
                */
                //change svg Tag to canvas Tag
                //get svg Tag html
                //.data方法傳入的是chart類型.如果是kendoRadialGauge,那么.data傳入的是'kendoRadialGauge';
                var svgTagHtml = $("#chart").data("kendoChart").svg();
                var canvasHtml = '<canvas id="kendoChart_canvas"></canvas>';
                $("#chart").empty().html(canvasHtml);
                canvg(document.getElementById('kendoChart_canvas'), svgTagHtml);
                
                });

 

 

  如果將最后四行代碼注釋,得到SVG圖形。如果不注釋最后四行代碼得到canvas。(這里都要執行kendoChart去繪制SVG,是為了得到圖形的SVG標簽html,到現在我還沒找到更好的解決方案)。

  

  注釋轉化代碼的截圖(SVG標簽):

 

 

  不注釋轉換代碼的截圖(canvas標簽):  

 

 

  兩種標簽得到的效果相同:

  缺陷:不管探測到瀏覽器是否支持SVG,都要執行kendoChart去繪制SVG,是為了得到圖形的SVG標簽html,到現在我還沒找到更好的解決方案。

  使用canvas后iScroll一起使用還有點問題,要去研究下canvas標簽和canvg方法的第三個參數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM