#javascript #jquery #css #d3.js #svg
#javascript #jquery #css #d3.js #svg
Вопрос:
В настоящее время я работаю с D3, чтобы нарисовать линейную диаграмму на svg. Я хочу сохранить svg, который работает нормально. Линейная диаграмма сохраняется, но добавленное мной фоновое изображение не отображается. Я просто получаю простой цветной фон.
Вот краткий пример того, как я добавляю фон и как я сохраняю svg. Это упрощенный пример, без линейного графика и с изображением, найденным в Интернете. Изначально фоновое изображение загружается из папки на веб-сервере. Результат, однако, тот же. При сохранении фонового изображения фоновое изображение отсутствует. В этом нет css.
http://jsfiddle.net/uphytob3/3/
Это часть сценария.
$("button.save_button").click(function() {
if ($(this).attr("value") == "export_image") {
save_svg();
}
});
var canvas = d3.select("#container")
.append("svg")
.attr("height", 440)
.attr("width", 503);
canvas.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#FAFAFA");
canvas.append("image")
.attr("xlink:href", "https://media.licdn.com/mpr/mpr/shrinknp_800_800/AAEAAQAAAAAAAANNAAAAJDU2MmE4ODEwLTQ1YTAtNGFjNi1iNmM5LTY4NGFiN2I0NmI5Yg.png")
.attr("x", 0)
.attr("y", 0)
.attr("width", 503)
.attr("height", 440)
.attr("opacity", 0.5);
function save_svg() {
var html = d3.select("svg")
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.node().parentNode.innerHTML;
var imgsrc = 'data:image/svg xml;base64,' btoa(html);
var canvas = document.createElement("canvas");
canvas.height = 700;
canvas.width = 1400;
var context = canvas.getContext("2d");
var image = new Image;
image.src = imgsrc;
image.onload = function() {
context.drawImage(image, 0, 0);
var canvasdata = canvas.toDataURL("image/png");
var a = document.createElement("a");
a.download = "test.png";
a.href = canvasdata;
a.click();
};
}
Я тестировал повторное добавление изображения при сохранении svg, но это не сработало, потому что оно либо было скрыто за линейной диаграммой, поскольку линейная диаграмма непрозрачна, либо оно было поверх линейной диаграммы, скрывая ее части.
Это модифицированная функция save_svg().
function save_svg() {
var html = d3.select("svg")
.attr("version", 1.1)
.attr("xmlns", "http://www.w3.org/2000/svg")
.node().parentNode.innerHTML;
var imgsrc = 'data:image/svg xml;base64,' btoa(html);
var canvas = document.createElement("canvas");
canvas.height = 700;
canvas.width = 1400;
var context = canvas.getContext("2d");
var image = new Image;
image.src = imgsrc;
var bg = new Image;
bg.src = "https://media.licdn.com/mpr/mpr/shrinknp_800_800/AAEAAQAAAAAAAANNAAAAJDU2MmE4ODEwLTQ1YTAtNGFjNi1iNmM5LTY4NGFiN2I0NmI5Yg.png";
image.onload = function() {
context.drawImage(image, 0, 0);
context.drawImage(bg, 0, 0);
var canvasdata = canvas.toDataURL("image/png");
var a = document.createElement("a");
a.download = "test.png";
a.href = canvasdata;
a.click();
};
Есть идеи о том, как получить фоновое изображение в сохраненном изображении?
Ответ №1:
Ваш вопрос неясен. Вы говорите о «отсутствии фона», но когда я пробую ваш код, я получаю PNG с серым фоном (#fafafa).
Так что, возможно, вы на самом деле говорите о картинке, которую вы добавили сверху? Тот, который из media.licdn.com ?
Причина, по которой вы не получаете это изображение в сохраненном файле PNG, заключается в ограничениях конфиденциальности в браузере. SVG, загружаемые как изображения, должны быть автономными. Они не могут ссылаться на сторонние объекты.
Вы загружаете SVG как изображение, загружая его как dataURI в new Image
. Загрузка SVG таким образом означает, что внешний файл, связанный с помощью <image>
, игнорируется.
Способы, которыми вы можете обойти это, могут быть:
-
преобразуйте стороннее изображение в URI данных и включите его таким образом в SVG. При этом он больше не является внешним ресурсом.
-
при сохранении SVG сначала нарисуйте его на холсте самостоятельно.
Комментарии:
1. Вы правы. Я обновил вопрос, чтобы сделать его более понятным. Поскольку jsfiddle не позволяет загружать изображения, мне пришлось использовать внешнее изображение для создания примера. Изначально я использую изображение, расположенное в папке img на веб-сервере. Будет ли оно по-прежнему считаться внешним?
2. ДА. Когда я говорю «внешний», я имею в виду внешний по отношению к SVG .