2017-06-14 3 views
0

ファブリックキャンバスの描画結果をSVGファイルに出力する必要があります。fabric.js出力svgにアルファ色を含めるにはどうすればよいですか?

fabric.jsバージョン1.7.6を使用していて、rgba(255,0,0,.15)のようなrgbaの塗りつぶしでキャンバスに描画されたパスがある場合、SVGの結果はrgb(0,0,0)となります。アルファチャンネルを出力するために有効にする必要がある設定がありますか?

私のサンプルコードでは、紫色の円は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、keywords)に変換されるので、アルファチャンネルをサポートしていません... – Kaiido

答えて

1

が、これはあなたがproject's issue trackerに報告すべきことは、バグのように見えます。当分の間、すべての(RGBA、HSL、HSLA、六角、キーワード))(RGBに変換されますので、アルファチャンネルをサポートしていません...

色は、ここに重い回避策です:

toSVGは、reviver関数を受け入れ、すべてのsvgノードマークアップを受け取ります。そこから、正しいスタイルを再適用できますが、それほど簡単には適用できません。

私たちが取得するsvgマークアップに対応するオブジェクトを特定できる唯一のパラメータは、idです。

  • まずは、私たちの色を保存する辞書をidで作成します。
  • 次に、ファブリックのオブジェクトにIDと色を割り当てます。
  • 最後に、リバイバーに、我々は、SVGのノードに変換し、そのid atributeを確認し、この修正されたノードのシリアライズを返す前に、その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

回避してくれてありがとう。私は要求どおりにバグを作成しました。他の誰かがこの状況に遭遇した場合に備えてここにリンクしてください。 https://github.com/kangax/fabric.js/issues/4004 偉大な図書館をありがとう! – nickvans

0

SVG仕様はCSS2形式で色を望んでいるので、RGBAがサポートされていないので、色がRGBに変換されます。

CIT:https://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#value-def-color

ファブリックが充填不透明ルイと透明性を満たします。ポイントは、fabric.Colorカラーパーサーがアルファチャンネルの表記.15を超えて窒息しているように見えることです。

0.15を使用してください。うまくいきます。

私は、このためにfabric.Colorを修正できることに同意します。

関連する問題