解决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网站上写着的):

  这里我用到了第二种方法,也就是将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 = '';
                      $("#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 = '';
                $("#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方法的第三个参数。

  本文来自answer1991的博客,原文地址:http://www.cnblogs.com/answer1991/archive/2012/07/24/2607481.html

你可能感兴趣的:(HTML5)