我們知道canvas畫布可以很方便的js原生支持轉為圖片格式並下載,但是svg矢量圖形則並沒有這方面原生的支持。研究過HighChart的svg圖形的圖片下載機制,其實現原理大體是瀏覽器端收集SVG代碼信息,併發送到到伺服器端,由後端程式轉換成圖片格式後,以流的形式反射給瀏覽器端下載。 最近在項目中 ...
我們知道canvas畫布可以很方便的js原生支持轉為圖片格式並下載,但是svg矢量圖形則並沒有這方面原生的支持。
研究過HighChart的svg圖形的圖片下載機制,其實現原理大體是瀏覽器端收集SVG代碼信息,併發送到到伺服器端,由後端程式轉換成圖片格式後,以流的形式反射給瀏覽器端下載。
最近在項目中有需求將一個非HighChart的SVG地圖轉存為圖片並下載的功能。
本希望模擬HighChart的原理實現,可是研究發現,該地圖的SVG代碼信息多達兩萬位元組,然而HighChart後端製圖程式卻有著位元組數限制,所以就不能這麼處理了。
然後國外社區討論的方法也多是前後端協同處理來完成這個功能的,這樣實現會比較重, 而且部署不便。
經過一番搜尋,終於發現一個不依賴任何外部庫,框架,同時僅僅通過瀏覽器端js便能實現的方法。 代碼實現的具體來源地址已經忘記了, 這裡保留代碼原創作者的版權哈。
首先,我們約定SVG的上下文結構是如下的:
<div class="svg-wrap">
<svg>...</svg>
</div>
然後,我們就可以通過如下代碼來將svg圖形轉為圖片並下載了:
var svgXml = $('.svg-wrap').html();
var image = new Image();
image.src = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgXml))); //給圖片對象寫入base64編碼的svg流
var canvas = document.createElement('canvas'); //準備空畫布
canvas.width = $('.svg-wrap svg').width();
canvas.height = $('.svg-wrap svg').height();
var context = canvas.getContext('2d'); //取得畫布的2d繪圖上下文
context.drawImage(image, 0, 0);
var a = document.createElement('a');
a.href = canvas.toDataURL('image/png'); //將畫布內的信息導出為png圖片數據
a.download = "MapByMathArtSys"; //設定下載名稱
a.click(); //點擊觸發下載