2016-12-20 24 views
2

Meteorでfabric.jsを使用しています。Fabric.js:パターンとしてSVGを使用し、SVGパターンの塗りつぶしを調整します

私はパスグループ内のパス上のパターンとして使用している次のSVGイメージを持っています。

enter image description here

あなたはそれにいくつかの透明性がある見ることができるように。

私がしたいことは、このパターンでパスを塗りつぶしてから、カラーピッカーを使ってその色を操作できるようにすることです。 SVGをパターンとして追加し、パスを複製して不透明度50%のカラーで塗りつぶすことで、これまでこれを行うことができましたが、パターンの色だけでなく、領域の色も変わります。基本的にパターンはパスの「塗りつぶし」なので、パターン自体をどのように埋めるのですか?

はここ

enter image description here

...よりよく説明するための図だここで私は特定のパターンが(流星のイベントを使用して)ドロップダウンリストから選択されたときにパターンを追加するために使用していたコードです...

'change .shapeTopPattern': function(e, template){ e.preventDefault(); 

     var textureID = e.target.value; 

     if(textureID != '') { //If this shape has a texture selected. 
      var texture = Textures.findOne(textureID); 

      //Get the image 
      var textureIMG = new Image; 
      textureIMG.crossOrigin = "anonymous"; 
      textureIMG.src = texture.image; 

      var patternURL = textureIMG.src; 
      fabric.Image.fromURL(patternURL, function(img) { 

       var obj = canvas.getActiveObject(); 
       var paths = obj.paths; 

       paths.forEach(function(p) { 
       if (p.pathName == "shapeTopTexture") { 
        img.width = p.width; 
        img.height = p.height 

        var patternSourceCanvas = new fabric.StaticCanvas(); 
        patternSourceCanvas.add(img); 
        patternSourceCanvas.setDimensions({ 
         width: p.width, 
         height: p.height 
         }); 
        var texture = patternSourceCanvas.getElement(); 

        var pattern = new fabric.Pattern({ 
         source: texture, 
         repeat: 'no-repeat', 
         offsetX: p.width/2, 
         offsetY: p.height/2 
        }); 

        obj.setFill(); 

        if (obj instanceof fabric.PathGroup) { 
         p.fill = pattern; 
         obj.perPixelTargetFind = false; 
        } else { 
         obj.setFill(pattern); 
        } 
        canvas.renderAll(); 
       } 
       }); 
      }); 

     } 
    }, 

これは、カラーピッカーの変更イベントで使用している関数です。 "shapeTopPatternColour"は、シリンダのパスグループからの複製されたパス(シリンダの上端)です。私はこれが明らかになぜ色がパターンの代わりに全体の領域に行き渡っているのかを知っていますが、私が望んだところにもっとも近い色です。

changeTopPatternColour = function(o, color, opacity) { 
    /* 
    * o = object 
    * color = rgbcolor data 
    * opacity = .5 
    */ 
    var paths = o.paths; 
    paths.forEach(function(p) { 
     if (p.pathName == "shapeTopPatternColour") { 
     p.setFill(color); 
     p.opacity = opacity; 
     } 
    }); 
    canvas.renderAll(); 
}; 

それでは、どのように私は...

  • (必要な場合のみ)パターンを追加し、SVGとしてそれを維持することができ、色と透明ではない部分でのみパターンのアルファを埋めますか?

ありがとうございます。

+0

素敵な質問の最初のパスを使用しています、あなたがイメージと共有することができsvgしてください? – InferOn

+0

どういう意味ですか?実際のファイルは?ここに[円柱オブジェクト](https://drive.google.com/open?id = 0B6eN38oOspCKVUt6TlFiYmNvdWc)、ここに[パターン](https://drive.google.com/open?id=0B6eN38oOspCKbElEUHZRNGZUZkk)があります。おかげで – Serks

答えて

1

残念ながら、必ずしもラスタライズせずにsvgファイルのパターンとして使用する方法を見つけることができませんでした。申し訳ありません。下の例では、私が常にサーフェスを完全に書き換えていることがわかります。 イメージのようにsvgをロードする代わりに、svgを正常にロードしてから、パスグループを使用してキャンバスに追加します。このスニペットでは、あなたのファイルを文字列として使用してCORSの厄介な問題を回避しています。

Here you can find the bitbucket repository

すべてのベスト。

$(function() { 
 
    var canvas = new fabric.Canvas('c'); 
 
    canvas.setWidth(600); 
 
    canvas.setHeight(370); 
 
    var tint = function(color) { 
 
    canvas.clear(); 
 
    var svgObjectString = '<?xml version="1.0" encoding="utf-8"?>' + 
 
     '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' + 
 
     ' viewBox="0 0 596 366" style="enable-background:new 0 0 596 366;" xml:space="preserve">' + 
 
     '<style type="text/css">' + 
 
     '.st0{fill:#E0E0E0;}' + 
 
     ' .st1{fill:url(#SVGID_1_);}' + 
 
     '</style>' + 
 
     '<path class="st0" d="M596,103.5c0,32-41.7,60.5-107.2,79.5c-51.7,15-118.2,24-190.8,24s-139.1-9-190.8-24C41.7,164,0,135.4,0,103.5' + 
 
     'c0-0.2,0-0.3,0-0.5C0.8,46.1,133.9,0,298,0s297.2,46.1,298,103C596,103.2,596,103.3,596,103.5z"/>' + 
 
     '<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="0" y1="133.25" x2="596" y2="133.25" gradientTransform="matrix(1 0 0 -1 0 368)">' + 
 
     '<stop offset="0" style="stop-color:#E8E8E8"/>' + 
 
     '<stop offset="0.23" style="stop-color:#878787"/>' + 
 
     '<stop offset="0.6" style="stop-color:#D6D6D6"/>' + 
 
     '<stop offset="1" style="stop-color:#ADADAD"/>' + 
 
     '</linearGradient>' + 
 
     '<path class="st1" d="M596,103.5v159c0,0.2,0,0.3,0,0.5c-0.8,56.9-133.9,103-298,103S0.8,319.9,0,263c0-0.2,0-0.3,0-0.5v-159' + 
 
     'c0,32,41.7,60.5,107.2,79.5c51.7,15,118.2,24,190.8,24s139.1-9,190.8-24C554.3,164,596,135.4,596,103.5z"/>' + 
 
     '</svg>'; 
 
    fabric.loadSVGFromString(svgObjectString, function(svgobject) { 
 
     //fabric.loadSVGFromURL('../../Content/object.svg', function (svgobject) { 
 
     var objGroup = new fabric.PathGroup(svgobject, { 
 
     width: 596, 
 
     height: 500 
 
     }); 
 
     canvas.add(objGroup); 
 

 
     var svgPatternString = '<?xml version="1.0" encoding="utf-8"?>' + 
 
     '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + 
 
     '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' + 
 
     ' width="576px" height="576px" viewBox="0 0 576 576" enable-background="new 0 0 576 576" xml:space="preserve">' + 
 
     '<polygon fill="#848484" points="290.664,286.625 244.214,729.625 338.422,729.625 "/>' + 
 
     '<polygon fill="#848484" points="290.711,286.625 337.16,-156.375 242.953,-156.375 "/>' + 
 
     '<polygon fill="#848484" points="290.688,286.602 -152.312,240.152 -152.312,334.359 "/>' + 
 
     '<polygon fill="#848484" points="290.688,286.648 733.688,333.098 733.688,238.89 "/>' + 
 
     '<polygon fill="#848484" points="290.664,286.625 244.214,729.625 338.422,729.625 "/>' + 
 
     '<polygon fill="#848484" points="290.711,286.625 337.16,-156.375 242.953,-156.375 "/>' + 
 
     '<polygon fill="#848484" points="290.688,286.602 -152.312,240.152 -152.312,334.359 "/>' + 
 
     '<polygon fill="#848484" points="290.688,286.648 733.688,333.098 733.688,238.89 "/>' + 
 
     '<polygon fill="#848484" points="290.666,286.616 75.532,676.646 162.318,713.297 "/>' + 
 
     '<polygon fill="#848484" points="290.709,286.634 505.843,-103.396 419.057,-140.047 "/>' + 
 
     '<polygon fill="#848484" points="290.696,286.604 -99.334,71.469 -135.984,158.255 "/>' + 
 
     '<polygon fill="#848484" points="290.679,286.646 680.709,501.78 717.359,414.994 "/>' + 
 
     '<polygon fill="#848484" points="290.671,286.608 -59.646,561.716 5.948,629.336 "/>' + 
 
     '<polygon fill="#848484" points="290.704,286.642 641.021,11.534 575.427,-56.086 "/>' + 
 
     '<polygon fill="#848484" points="290.704,286.609 15.597,-63.709 -52.024,1.885 "/>' + 
 
     '<polygon fill="#848484" points="290.671,286.641 565.778,636.958 633.398,571.364 "/>' + 
 
     '<polygon fill="#848484" points="290.679,286.603 -137.942,407.811 -102.993,495.296 "/>' + 
 
     '<polygon fill="#848484" points="290.696,286.647 719.315,165.439 684.367,77.954 "/>' + 
 
     '<polygon fill="#848484" points="290.709,286.617 169.502,-142.004 82.016,-107.055 "/>' + 
 
     '<polygon fill="#848484" points="290.666,286.634 411.873,715.253 499.358,680.305 "/>' + 
 
     '</svg>'; 
 

 
     fabric.loadSVGFromString(svgPatternString, function(svgpattern) { 
 
     //fabric.loadSVGFromURL('../../Content/pattern.svg', 
 
     // function (svgpattern) { 
 
     svgpattern.map(function(item) { 
 
      item.fill = color; 
 
     }); 
 
     var ptnGroup = new fabric.PathGroup(svgpattern, { 
 
      top: -190, 
 
      width: 596, 
 
      height: 500 
 
     }); 
 
     var paths = objGroup.paths; 
 
     var path = paths[0]; 
 
     svgpattern.width = path.width; 
 
     svgpattern.height = path.height; 
 
     var patternSourceCanvas = new fabric.StaticCanvas(); 
 
     patternSourceCanvas.add(ptnGroup); 
 
     patternSourceCanvas.setDimensions({ 
 
      width: path.width, 
 
      height: path.height 
 
     }); 
 
     var texture = patternSourceCanvas.getElement(); 
 
     var pattern = new fabric.Pattern({ 
 
      source: texture, 
 
      repeat: 'no-repeat', 
 
      offsetX: path.width/2, 
 
      offsetY: path.height/2 
 
     }); 
 
     objGroup.setFill(); 
 
     objGroup.globalCompositeOperation = "source-over"; 
 
     path.setFill("#ff0000"); 
 
     path.fill = pattern; 
 
     objGroup.perPixelTargetFind = false; 
 
     canvas.renderAll(); 
 
     }); 
 
    }); 
 
    } 
 
    $('button') 
 
    .on('click', 
 
     function(e, args) { 
 
     tint(e.target.value); 
 
     }); 
 
});
canvas { 
 
    border: 1px solid #ccc; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.2/fabric.min.js"></script> 
 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="container"> 
 
    <div class="row"> 
 
    <div class="col-md-7"> 
 
     <canvas id="c" style="border: solid 1px #ccc;"></canvas> 
 
    </div> 
 
    <div class="col-md-5"> 
 
     <button class="btn-danger" value="red">red</button> 
 
     <button class="btn-success" value="green">green</button> 
 
     <button class="btn-primary" value="blue">blue</button> 
 
    </div> 
 
    </div> 
 
</div>

編集:あなたのシリンダーの上部の寸法を取得するために、私はsvgobject

var paths = objGroup.paths; 
var path = paths[0]; 
svgpattern.width = path.width; 
svgpattern.height = path.height; 
var patternSourceCanvas = new fabric.StaticCanvas(); 
patternSourceCanvas.add(ptnGroup); 
patternSourceCanvas.setDimensions({ 
    width: path.width, 
    height: path.height 
}); 
+0

あなたの答えをありがとう、しかし、私はパターンをオブジェクトの上面の幅と高さに一致するように取得することに問題があります。 'new fabric.PathGroup'内の幅と高さの値は、サイズを変更する代わりにパターン[私がここで意味するものを参照](https://drive.google.com/open?id=0B6eN38oOspCKSUdRNFRfcENLbUk)を切り取っているようです。他の幅と高さの値( 'svgpattern.width = path.width;'と 'patternSourceCanvas.setDimensions')は何もしていないようです。 – Serks

+0

functionにcolorpickerを接続しようとすると、さらに問題が発生しているようです。この関数が関数全体を再実行せずに実行された後、塗りつぶしの色だけを変更することはできますか? – Serks

+0

色の変更後にパターンをラスタライズする必要があるので、私の意見では問題になる可能性があります。別のオプションが表示されない、ごめんなさい。 – InferOn

関連する問題