Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 755|回复: 0

解决html5 + js开发APP无法显示SVG问题(转化成canvas)

[复制链接]
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 793 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    723458
    发表于 2021-7-5 16:04:47 | 显示全部楼层 |阅读模式

      项目里用到了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方法的第三个参数。

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-21 07:19 , Processed in 0.064983 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表