У меня есть приложение, которое строит диаграмму с использованием svg, и я хочу загрузить PNG-изображение пользователю. Я использую polysills FileSaver.js и canvas-to-blob.min.js, чтобы получить поддержку canvas.toBlob() и window.saveAs().Как преобразовать SVG-узел в PNG и загрузить его пользователю?
Вот фрагмент кода, приложенный к кнопке загрузки:
$('#download-button').on('click', function(e) {
e.preventDefault();
var chart = $('#bar-chart')
.attr('xmlns', 'http://www.w3.org/2000/svg');
var width = chart.width();
var height = chart.height();
var data = new XMLSerializer().serializeToString(chart.get(0));
var svg = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
var url = URL.createObjectURL(svg);
var img = $('<img />')
.width(width)
.height(height)
.on('load', function() {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img.get(0), 0, 0);
canvas.toBlob(function(blob) {
saveAs(blob, "test.png");
});
});
img.attr('src', url);
});
Он извлекает из XML-для изображения SVG, заворачивает в сгустке и создает объект URL для сгустка. Затем он создает объект изображения и устанавливает его src в URL-адрес объекта. Обработчик события нагрузки создает холст и использует drawImage() для рендеринга изображения на холст. Наконец, он извлекает данные изображения во второй blob и использует saveAs(), чтобы загрузить его как «test.png».
Все работает, но загруженный файл PNG не имеет всего изображения - всего лишь часть верхнего левого угла. Может ли браузер запускать событие «load» до того, как SVG будет полностью отображен? Или я просто что-то пропустил?
Here is a jsFiddle demonstrating the problem.
100% -ная ширина элемента SVG интерпретируется как 100 пикселей. Вы можете увидеть это, если вы console.log ширину/высоту. Установка абсолютной ширины - один из способов решения проблемы. – K3N
Спасибо, Кен - это сделал. – scottb