Подтвердить что ты не робот

Получить SVG из элемента холста и сохранить его

В настоящее время я создаю небольшое приложение для друга, который начинает его PhD и должен построить некоторые сетевые графики. Пока все работает отлично, используя граф с направленной силой. Узлы графов могут перемещаться в стиле макета.

SsGFz.png

Вещь, с которой я не могу оглянуться, - это:

", как извлечь данные с холста и сохранить его в SVG файле" .

Что я пробовал:

Я уже пробовал получить доступ к изображению Данные из консоли с помощью

var app.canvas = document.getElementById( 'graph-canvas' )
    .getContext( '2d' )
        .getImageData( 0, 0, 200, 200 );

и получил (object) ImageData взамен. Теперь я могу получить доступ к отображаемым данным холста ↑ с помощью app.canvas.data. (Когда я пытаюсь также просмотреть значения, браузер начинает зависать и спрашивает, следует ли остановить script - последние версии Chrome и FF).

Как мне перейти отсюда, чтобы получить SVG, а затем сохранить его одним нажатием кнопки?

EDIT:

До сих пор я узнал, как нарисовать SVG и добавить к нему элемент image/png. Как бы то ни было, он не отображается.

// Add the test SVG el:
var svg = document.createElementNS( "http://www.w3.org/2000/svg", "svg" );
svg.setAttribute( 'style', 'border: 1px solid black;' )
        .setAttribute( 'width', '600' )
        .setAttribute( 'height', '400' )
        .setAttributeNS(
            'http://www.w3.org/2000/xmlns/',
            'xmlns:xlink',
            'http://www.w3.org/1999/xlink'
        );

// Call
importCanvas( document.getElementById( 'infovis-canvas' ), svg ); 

// Function: Add data to SVG
function importCanvas( sourceCanvas, targetSVG ) 
{
    // get base64 encoded png data url from Canvas
    var img_dataurl = sourceCanvas.toDataURL( "image/png" );

    var svg_img = document.createElementNS(
        "http://www.w3.org/2000/svg",
        "image"
    );

    svg_img.setAttributeNS(
        'http://www.w3.org/1999/xlink',
        'xlink:href',
        img_dataurl
    );
    jQuery( targetSVG.appendChild( svg_img ) )
        .appendTo( '#graph-container' );

    console.log( 'done' ); // Log & confirm
}

И, наконец,...

// ...resulting SVG element containing the image element
<svg style="border: 1px solid black;" width="600" height="400" xlink="http://www.w3.org/1999/xlink"><image href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAA(...)

Пользовательский интерфейс работает с jQuery UI, jQuery и Библиотека Jit/InfoVIZ, поэтому они доступны.

4b9b3361

Ответ 1

Если вы хотите сохранить его как векторный рисунок, а не как растр, вы можете попробовать одну из библиотек, которые преобразуют операции API холста в svg.

Для SVGKit:

var svgkitContext = new SVGCanvas(150,150);

function draw(ctx) {
   // ... normal canvas drawing commands go here ...
}

// draw to SVGKit canvas (svg) instead of canvasElement.getContext("2d")
draw(svgkitContext);

Полный запуск example выше.

Для canvas-svg:

var canvasSVGContext = new CanvasSVG.Deferred();
canvasSVGContext.wrapCanvas(document.querySelector("canvas"));
var canvasContext = document.querySelector("canvas").getContext("2d");

function draw(ctx) {
    // ... normal canvas drawing commands go here ...
}

// draw to html5 canvas and record as svg at the same time
draw(canvasContext);

// append the svg result
var svg = document.appendChild(canvasContext.getSVG());

Полный запуск пример выше.

Для генерации вместо svg:

Другим вариантом является, конечно, сделать граф как svg в первую очередь, d3.js - это библиотека javascript, которая упрощает для этого см., например, этот пример диаграммы направленности силы.

Ответ 2

Если вы ограничены ImageData, вам не повезло, потому что это всего лишь простой пиксельный массив (см. ссылка). Оттуда вы не сможете получить значимый SVG-образ. Вероятно, вы можете снять представление .png... но это статическое изображение без взаимодействия.

Если вы собираетесь сделать какой-то холст для экспорта SVG, важно, как вы делаете рисунок холста. Лучшим подходом было бы использовать библиотеку, которая поддерживает холст график сцены.

Fabric.js кажется хорошим выбором. Вы можете сделать рисунок с холстом, а затем вызвать canvas.toSVG() и получить изображение svg.