zoukankan      html  css  js  c++  java
  • 绘制SVG内容到Canvas的HTML5应用

    SVG与Canvas是HTML5上绘制图形应用的两种完全不同模式的技术,两种绘制图形方式各有优缺点,但两者并非水火不容,尤其是SVG内容可直接绘制在Canvas上的功能,使得两者可以完美的融合在一起,让Canvas可享用到现有丰富的SVG素材,并不失SVG矢量无级缩放的特点。

    基于HTML5的Drag and Drop生成图片Base64信息》这篇虽然展示的是拖拽普通栅格图片的效果,但你也可以直接拖拽SVG格式的图片进行显示,只不过普通图片的格式数据为data:image/png类型,而SVG格式的数据类型为data:image/svg+xml的类型,下图为该HT for Web拓扑图拖拽入SVG格式图片的运行效果:

    Screen Shot 2015-02-01 at 2.20.40 PM

    以下一段小例子,展示了加载一个SVG图片后,分为七个基本进行缩放绘制的效果,可看出Canvas绘制SVG可保持其矢量不失真的特性

    function draw(){
        var img = new Image();
        img.src = 'chart.svg';
        document.body.appendChild(img);
        img.onload = function(){
            var canvas = document.getElementById('canvas');
            var g = canvas.getContext('2d'); 
            var width = img.clientWidth * 1.5;
            var height = img.clientHeight * 1.5;                
            var x = 2;
            var y = 2;
            for(var i=0; i<7; i++){
                g.drawImage(img, x, y, width, height);
                x += width + 2;
                width /= 2;
                height /= 2;
            }            
        };
    }

    Screen Shot 2015-02-01 at 2.21.39 PM

    提到Canvas和SVG的融合,我们将采用HT for Web的矢量功能展示一个手机电池充电进度的实例,整个手机电池的静态部分我们通过加载一个简单的SVG素材实现,而充电动态变化的部分,我们采用一个渐进色的HT矩形元素来描述,该矩形的长度通过HT矢量数据动态绑定功能,根据充电进度的百分比换算成长度信息,最后通过定时器模拟数据变化达到动态充电的效果:


    Screen Shot 2015-02-01 at 2.21.21 PM

    ht.Default.setImage('battery', {
         64,
        height: 64,
        comps: [   
            {
                type: 'rect',
                rect: {
                    func: function(data){
                        return [5, 25, 50*data.a('percent'), 16]
                    }
                },
                background: 'red',
                gradient: 'spread.vertical'
            },                        
            {
                type: 'image',
                name: 'battery.svg',
                relative: true,
                rect: [0, 0, 1, 1]
            }
        ]
    });               
    
    var node = new ht.Node();
    node.setPosition(80, 150);
    node.setImage('battery');
    node.s('image.stretch', 'uniform');
    node.a('percent', 0);
    dataModel.add(node);   
    
    graphView.setEditable(true);
    
    setInterval(function(){
        percent = node.a('percent') + 0.02;
        if(percent > 1){
            percent = 0;
        }
        node.a('percent', percent);
    }, 16);

    SVG绘制到Canvas还有一种特殊的应用场景,就是将HTML元素通过SVG的foreignObject特性描述在SVG中,然后Canvas绘制SVG时,即可把foreignObject描述的HTML内容绘制到Canvas上,可参见https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas 的实例,其中采用了Blob的方式设置img的src作为URL是比较怪异的技术点,但从上文提到其实我们可以将整个SVG内容转换成data:image/svg+xml;的base64内容即可作为src的url传入,因此我对该例子做了改造,采用btoa(data)把svg内容转换成base64的方式设置img.src,这样方式更容易理解,例子代码和效果如下:http://v.youku.com/v_show/id_XODg0MTU4NjEy.html

    Screen Shot 2015-02-01 at 2.21.56 PM

    function draw(){
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var data = 。。。;
        var img = new Image();
        img.onload = function () {
            ctx.drawImage(img, 0, 0);
        };            
        img.src = 'data:image/svg+xml;base64,' + btoa(data);
    }

  • 相关阅读:
    luogu1060开心的金明
    luogu1048采药
    uva1025城市里的间谍
    scoi刷题记录(2019/04/07)
    差分及树上差分的正确食用姿势(2019/2/21学习笔记)
    图论技巧(2019/1/28之一)
    考试反思(2019/1/26学习笔记)
    考试反思(2019/1/22)
    「一本通 5.2 例 5」皇宫看守
    「一本通 5.2 例 3」数字转换
  • 原文地址:https://www.cnblogs.com/xhload3d/p/4265589.html
Copyright © 2011-2022 走看看