2017-06-14 28 views
0

我需要将结构画布绘制的结果输出到SVG文件。如何让fabric.js输出svg包括alpha颜色?

我使用的是fabric.js版本1.7.6,当我有一个用rgba填充类似于rgba(255,0,0,.15)的画布绘制的路径时,生成的SVG填充为rgb(0,0,0)。我需要启用一些设置才能输出alpha通道?

在我的示例代码中,紫色圆圈正确转换为SVG,但矩形只显示为黑色。

样本HTML:

<html> 
    <head> 
    <script src="fabric.js"></script> 
    </head> 
    <body> 

    <div id="canvasHolder" style="border: 3px solid black;"> 
     <canvas id="canvasElement" width="400" height="400" /> 
    </div> 

    <div id="svgHolder" style="border: 3px solid blue;"> 
    </div> 
    </body> 

    <script> 
    var canvas = new fabric.Canvas('canvasElement'); 

    var rect = new fabric.Path('M,0,0,h,100,v,100,h,-100,z',{ 
     top:100, 
     left:100, 
     stroke: 'green', 
     fill: 'rgba(255,0,0,.15)' 
    }); 
    canvas.add(rect); 

    var circ = new fabric.Circle({ 
     radius: 30, 
     top:30, 
     left:30, 
     stroke: 'blue', 
     fill: 'purple' 
    }); 
    canvas.add(circ); 

    canvas.renderAll(); 

    // Make an SVG object out of the fabric canvas 
    var SVG = canvas.toSVG(); 
    document.getElementById('svgHolder').innerHTML = SVG; 
    </script> 

</html> 

输出SVG:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="400" height="400" viewBox="0 0 400 400" xml:space="preserve"> 
<desc>Created with Fabric.js 1.7.6</desc> 
<defs> 
</defs> 
<path d="M 0 0 h 100 v 100 h -100 z" style="stroke: rgb(0,128,0); stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;" transform="translate(150.5 150.5) translate(-50, -50) " stroke-linecap="round"></path> 
</svg> 
+0

看起来像一个错误,你应该报告[项目的问题跟踪器](https://github.com/kangax/fabric.js/issues/new)。颜色全部转换为'rgb()'('hsl',hex,关键字),因此不支持alpha通道... – Kaiido

回答

1

正如我在评论说,这看起来像一个错误,你应该在project's issue tracker报告。

颜色都是转换成RGB()(RGBA,HSL,HSLA,六角,关键字),因此不支持alpha通道...

暂且,这里是一个沉重的解决方法:

toSVG接受reviver函数,它将接收所有的svg节点标记。从那里,你可以重新应用正确的样式,但不是那么容易。

我可以找到的唯一参数允许我们确定哪个对象与我们获得的svg标记相对应的是id之一。

  • 首先,我们将构建一个字典,它将通过id存储我们的颜色。
  • 然后,我们会将id和颜色分配给织物的物体。
  • 最后,在齐磊,我们会分析我们的标记,以将其转换为SVG节点,检查其id属性附加伤害,然后改变其style.fillstyle.stroke性质,返回此修改节点的串行化之前。

var canvas = new fabric.Canvas('canvasElement'); 
 

 
var colors_dict = {}; 
 
// an helper function to generate and store our colors objects 
 
function getColorId(fill, stroke) { 
 
    var id = 'c_' + Math.random() * 10e16; 
 
    return colors_dict[id] = { 
 
    id: id, 
 
    fill: fill || 'black', 
 
    stroke: stroke || 'black' // weirdly fabric doesn't support 'none' 
 
    } 
 
} 
 

 
// first ask for the color object of the rectangle 
 
var rect_color = getColorId('hsla(120, 50%, 50%, .5)', 'rgba(0,0,255, .25)'); 
 
var rect = new fabric.Path('M,0,0,h,100,v,100,h,-100,z', { 
 
    top: 60, 
 
    left: 60, 
 
    stroke: rect_color.stroke, // set the required stroke 
 
    fill: rect_color.fill, // fill 
 
    id: rect_color.id // and most importantly, the id 
 
}); 
 
canvas.add(rect); 
 

 
var circ_color = getColorId('rgba(200, 0,200, .7)'); 
 
var circ = new fabric.Circle({ 
 
    radius: 30, 
 
    top: 30, 
 
    left: 30, 
 
    stroke: circ_color.stroke, 
 
    fill: circ_color.fill, 
 
    id: circ_color.id 
 
}); 
 
canvas.add(circ); 
 

 
canvas.renderAll(); 
 

 
var parser = new DOMParser(); 
 
var serializer = new XMLSerializer(); 
 
function reviveColors(svg){ 
 
    // first we parse the markup we get, and extract the node we're interested in 
 
    var svg_doc = parser.parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + svg + '</svg>', 'image/svg+xml'); 
 
    var svg_node = svg_doc.documentElement.firstElementChild; 
 
    var id = svg_node.getAttribute('id'); 
 
    if (id && id in colors_dict) { // is this one of the colored nodes 
 
    var col = colors_dict[id]; // get back our color object 
 
    svg_node.style.fill = col.fill; // reapply the correct styles 
 
    svg_node.style.stroke = col.stroke; 
 
    // return the new markup 
 
    return serializer.serializeToString(svg_node).replace('xmlns="http://www.w3.org/2000/svg', ''); 
 
    } 
 
    return svg; 
 
} 
 

 
// Make an SVG object out of the fabric canvas 
 
var SVG = canvas.toSVG(null, reviveColors); 
 
document.getElementById('svgHolder').innerHTML = SVG;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.12/fabric.js"></script> 
 
<div id="canvasHolder" style="border: 3px solid black;"> 
 
<!-- beware canvas tag can't be self-closing --> 
 
<canvas id="canvasElement" width="400" height="200"></canvas> 
 
</div> 
 
<div id="svgHolder" style="border: 3px solid blue;">

+0

感谢您的解决。我按要求创建了一个bug。将其链接到此处以防其他人遇到这种情况。 https://github.com/kangax/fabric.js/issues/4004 感谢伟大的图书馆! – nickvans