繪制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', {
    width: 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);
}


免責聲明!

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



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