SVG與Canvas是HTML5上繪製圖形應用的兩種徹底不一樣模式的技術,兩種繪製圖形方式各有優缺點,但二者並不是水火不容,尤爲是SVG內容可直接繪製在Canvas上的功能,使得二者能夠完美的融合在一塊兒,讓Canvas可享用到現有豐富的SVG素材,並不失SVG矢量無級縮放的特色。html
《基於HTML5的Drag and Drop生成圖片Base64信息》這篇雖然展現的是拖拽普通柵格圖片的效果,但你也能夠直接拖拽SVG格式的圖片進行顯示,只不過普通圖片的格式數據爲data:image/png類型,而SVG格式的數據類型爲data:image/svg+xml的類型,下圖爲該HT for Web拓撲圖拖拽入SVG格式圖片的運行效果:node
如下一段小例子,展現了加載一個SVG圖片後,分爲七個基本進行縮放繪製的效果,可看出Canvas繪製SVG可保持其矢量不失真的特性canvas
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; } }; }
提到Canvas和SVG的融合,咱們將採用HT for Web的矢量功能展現一個手機電池充電進度的實例,整個手機電池的靜態部分咱們經過加載一個簡單的SVG素材實現,而充電動態變化的部分,咱們採用一個漸進色的HT矩形元素來描述,該矩形的長度經過HT矢量數據動態綁定功能,根據充電進度的百分比換算成長度信息,最後經過定時器模擬數據變化達到動態充電的效果:app
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.htmlsvg
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); }