从canvas元素获取SVG并保存

kai*_*ser 23 javascript svg canvas save

目前我正在为一位朋友创建一个小应用程序,他开始攻读博士学位并需要构建一些网络图.到目前为止,使用Force Directed图表一切正常.可以移动图形节点以设置布局样式.

我无法理解的是:

»如何从画布中提取数据并将其保存到SVG文件«.

我尝试了什么:

我已经尝试从控制台访问图像数据了

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

得到了一个(object) ImageData回报.现在我可以访问↑显示的画布数据了app.canvas.data.(当我尝试查找值时,浏览器开始挂起并询问是否应停止脚本 - Chrome&FF最新版).

我如何从这里获取SVG,然后通过单击按钮保存?

编辑:

到目前为止,我发现了如何绘制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
}
Run Code Online (Sandbox Code Playgroud)

最后......

// ...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(...)
Run Code Online (Sandbox Code Playgroud)

UI与jQuery UI,jQuery和The Jit/InfoVIZ库一起使用,因此可用.

Eri*_*röm 9

如果要将其保存为矢量图形而不是栅格,可以尝试将canvas 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);
Run Code Online (Sandbox Code Playgroud)

上面的完整运行示例.

对于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());
Run Code Online (Sandbox Code Playgroud)

上面的完整运行示例.

用于生成svg而不是:

另一种选择当然是首先将图形作为svg,d3.js是一个javascript库,可以很容易地做到这一点,参见例如力导向图的这个例子.


mih*_*hai 6

如果你只是ImageData因为运气不好,因为那只是一个像素阵列(参见参考资料).您无法从那里获得有意义的SVG图像.您可以拉出一个.png表示...但这是一个没有交互的静态图像.

如果您要为SVG导出执行某种画布,那么您在绘制画布的过程中非常重要.最好的方法是使用维护画布场景图的库.

Fabric.js似乎是一个不错的选择.您可以使用画布进行绘图,然后调用canvas.toSVG()并获取您的svg图像.