2013-11-26 8 views
3

У меня есть приложение, которое строит диаграмму с использованием 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.

+0

100% -ная ширина элемента SVG интерпретируется как 100 пикселей. Вы можете увидеть это, если вы console.log ширину/высоту. Установка абсолютной ширины - один из способов решения проблемы. – K3N

+0

Спасибо, Кен - это сделал. – scottb

ответ

4

(Moving комментарий, чтобы ответить на вопрос, так что может быть закрыт :)

Ширина элемента SVG 100% интерпретируется как 100 пикселей. Вы можете увидеть это, если вы console.log ширину/высоту.

Установка абсолютной ширины - это один из способов решения проблемы.

+0

Не следует путать с высотой и шириной атрибута стиля элемента. Установка атрибутов высоты и ширины элемента - это трюк. Пример: ' ...' –