در یکی از پروژهها نیاز بود تا کاربر بتواند یک تصویر svg را به صورت png دانلود کند (! نیازه دیگه چه میشه کرد!?)؛ با مقداری تحقیق و بررسی و ترکیب تعدادی کد با یکدیگر به این کد رسیدم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
function downloadVectorAsPng(vectorName) { var mySvg = document.getElementById(vectorName); var myCanvas = document.createElement('canvas'); myCanvas.style = "display: none;"; myCanvas.width = mySvg.clientWidth*5; myCanvas.height = mySvg.clientHeight*5; document.body.appendChild(myCanvas); var ctx = myCanvas.getContext('2d'); var svgData = (new XMLSerializer()).serializeToString(mySvg); var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svgBlob = new Blob([svgData], {type: 'image/svg+xml;charset=utf-8'}); var url = DOMURL.createObjectURL(svgBlob); img.onload = function () { ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, myCanvas.width, myCanvas.height); ctx.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); var imgURI = myCanvas .toDataURL('image/png') .replace('image/png', 'image/octet-stream'); var evt = new MouseEvent('click', { view: window, bubbles: false, cancelable: true }); var a = document.createElement('a'); a.setAttribute('download', 'VectorDiagram_' + new Date().toLocaleDateString() + '.png'); a.setAttribute('href', imgURI); a.setAttribute('target', '_blank'); a.dispatchEvent(evt); }; img.src = url; } |
روش کار کد به صورت خلاصه این است که ابتدا svg در یک متغیر ذخیره شده و سپس یک canvas نامرئی ساخته میشود؛ در ادامه تصویر svg درون canvas رسم شده و در نهایت با ترفندِ ساخت لینک مخفی و کلیک مصنوعی، تصویر برای کاربر دریافت میشود.
- ابعاد canvas بر مبنای ابعاد svg تنظیم میشود. برای اینکه تصویر زیادی کوچک نباشد، عرض و ارتفاع تصویر در 5 ضرب شده است که میتوانید آن را تغییر دهید.
- برای اینکه پسزمینه تصویر نهایی نامرئی نباشد، ابتدا یک مستطیل سفید در ابعاد کل canvas رسم شده (
ctx.fillRect) و سپس تصویر svg رسم میشود.