fabricjs中的模式填充使渲染变慢

时间:2015-11-18 07:10:01

标签: javascript html5 svg fabricjs

我试图在大图上制作剪辑蒙版效果 我所做的是将图片用作图案并将其设置为支持图形的svg路径。

在这里查看jsfiddle(可能有点慢)

http://jsfiddle.net/minzojian/xwurbwvn/

请检查上面的代码

enter image description here

结果还可以,但是当你拖动形状时,你会发现它不顺畅,为什么会这样?

如果图案不是最佳解决方案,那么如何制作不规则的剪辑蒙版效果?

2 个答案:

答案 0 :(得分:2)

1使用较小的模式

检查更新的小提琴。 http://jsfiddle.net/xwurbwvn/3/

 patternSourceCanvas.setDimensions({
     width: obj.width + 55,
     height: obj.height + 55
 });

有一件事是将用于创建图案的staticCanvas塑造成您要填充的对象的尺寸。 如你所见,有一个“加点东西”添加到画布。 这是因为图案填充会移动路径的一半宽度并再次向后移动(这是为了适应居中的变换),所以如果你没有那些额外的宽度,你会看到白色。

使用此解决方案,它更平滑,不是非常光滑,只是更顺畅。

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

 fabric.loadSVGFromURL('http://sharepage.lunastudio.cn/flower.svg', function (objects, options) {
 var obj = fabric.util.groupSVGElements(objects, options);
 fabric.Image.fromURL('http://sharepage.lunastudio.cn/Penguins.jpg', function (img) {
     var patternSourceCanvas = new fabric.StaticCanvas();
     patternSourceCanvas.setDimensions({
         width: obj.width + 55,
         height: obj.height + 55
     });
     patternSourceCanvas.add(img);

     var s = patternSourceCanvas.getElement();
     var pattern = new fabric.Pattern({
         source: s,
         repeat: 'no-repeat'
     });
     obj.paths.forEach(function(item) {
         item.fill = pattern;
     });
     canvas.add(obj);
 });
 });
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id='canvas' width="400" height="400" style="border:#000 1px solid;"></canvas>

2在单一形状上使用较小的图案

为了获得更流畅的体验,请优化您的svg,就像这个小提琴一样: http://jsfiddle.net/xwurbwvn/4/

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

 fabric.loadSVGFromURL('data:image/svg+xml;utf8,<?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"  width="345.657px" height="345.657px" viewBox="0 0 345.657 345.657" enable-background="new 0 0 345.657 345.657" xml:space="preserve"><g><path fill="#25A296" d="M111.14,35.006c16.891,16.892,0.734,52.632,13.953,88.862c-37.21-12.24-71.971,2.938-88.862-13.953 C21.787,95.472,23.012,78.091,34.272,66.83c6.854-6.854,18.359-7.834,27.907-5.875c-1.959-9.548-0.979-20.809,5.875-27.907 C79.315,21.787,96.696,20.563,111.14,35.006z M31.824,118.973c23.99,0,37.699,36.72,72.705,52.877c-35.006,17.625-48.96,52.877-72.705,52.877 C11.261,224.727,0,211.752,0,195.595c0-9.792,7.344-18.604,15.423-23.745C7.344,166.464,0,157.896,0,148.104 C0,131.947,11.261,118.973,31.824,118.973z M35.007,234.519c16.891-16.892,52.632-0.734,88.862-13.954c-12.24,37.21,2.938,71.972-13.954,88.862 c-14.443,14.443-31.824,13.22-43.085,1.959c-6.854-6.854-7.833-18.36-5.875-27.907c-9.547,1.958-20.808,0.979-27.907-5.875 C21.787,266.342,20.563,248.961,35.007,234.519z M118.973,313.833c0-23.99,36.72-37.699,52.877-72.705c17.625,35.006,52.877,48.96,52.877,72.705 c0,20.563-12.975,31.824-29.132,31.824c-9.792,0-18.604-7.344-23.745-15.422c-5.386,8.078-13.953,15.422-23.745,15.422 C131.947,345.657,118.973,334.396,118.973,313.833z M234.519,310.651c-16.892-16.892-0.734-52.633-13.954-88.862c37.21,12.239,71.972-2.938,88.862,13.953 c14.443,14.443,13.22,31.824,1.959,43.085c-6.854,6.854-18.36,7.833-27.907,5.875c1.958,9.547,0.979,20.808-5.875,27.907 C266.342,323.87,248.962,325.094,234.519,310.651z M313.833,226.685c-23.99,0-37.699-36.72-72.705-52.877c35.006-17.626,48.96-52.877,72.705-52.877 c20.563,0,31.824,12.975,31.824,29.131c0,9.792-7.344,18.605-15.422,23.746c8.078,5.386,15.422,13.953,15.422,23.745 C345.657,213.71,334.396,226.685,313.833,226.685z M310.651,111.139c-16.892,16.892-52.633,0.734-88.862,13.954c12.239-37.21-2.938-71.972,13.953-88.862 c14.443-14.443,31.824-13.22,43.085-1.959c6.854,6.854,7.833,18.36,5.875,27.907c9.547-1.958,20.808-0.979,27.907,5.875 C323.87,79.314,325.094,96.695,310.651,111.139z M120.687,31.823c0,23.991,36.72,39.413,52.877,74.42c17.625-35.007,52.876-50.674,52.876-74.42 C226.439,11.261,213.466,0,197.309,0c-9.792,0-18.604,7.344-23.745,15.422C168.178,7.344,159.609,0,149.817,0 C133.661,0,120.687,11.261,120.687,31.823z" /></g></svg>', function (objects, options) {
 var obj = fabric.util.groupSVGElements(objects, options);
 fabric.Image.fromURL('http://sharepage.lunastudio.cn/Penguins.jpg', function (img) {
     var patternSourceCanvas = new fabric.StaticCanvas();
     patternSourceCanvas.add(img);
     patternSourceCanvas.renderAll();
     patternSourceCanvas.setDimensions({
         width: obj.getWidth() * 1.5,
         height: obj.getHeight() * 1.5
     });
     var s = patternSourceCanvas.getElement();

     var pattern = new fabric.Pattern({
         source: s,
         repeat: 'no-repeat'
     });
     obj.paths.forEach(function (item) {
         item.fill = pattern;
     });
     canvas.add(obj);
     canvas.renderAll();
 });

 });
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id='canvas' width="400" height="400" style="border:#000 1px solid;"></canvas>

这里SVG是作为单一路径创建的,因此结构只需要一个patternFill而不是8个(每个壁炉一个)

3使用替代

这是制作剪辑路径的最佳方式。

这取决于你剪裁的是什么。

你基本上有3种方式: 图案填充形状(不剪裁) 用路径剪切图像 使用globalCompositeOperation

要剪切图像,你必须有一个单一的形状,而不是其中的8个,所以基本上用我的第二个例子:

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

 fabric.loadSVGFromURL('data:image/svg+xml;utf8,<?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"  width="345.657px" height="345.657px" viewBox="0 0 345.657 345.657" enable-background="new 0 0 345.657 345.657" xml:space="preserve"><g><path fill="#25A296" d="M111.14,35.006c16.891,16.892,0.734,52.632,13.953,88.862c-37.21-12.24-71.971,2.938-88.862-13.953 C21.787,95.472,23.012,78.091,34.272,66.83c6.854-6.854,18.359-7.834,27.907-5.875c-1.959-9.548-0.979-20.809,5.875-27.907 C79.315,21.787,96.696,20.563,111.14,35.006z M31.824,118.973c23.99,0,37.699,36.72,72.705,52.877c-35.006,17.625-48.96,52.877-72.705,52.877 C11.261,224.727,0,211.752,0,195.595c0-9.792,7.344-18.604,15.423-23.745C7.344,166.464,0,157.896,0,148.104 C0,131.947,11.261,118.973,31.824,118.973z M35.007,234.519c16.891-16.892,52.632-0.734,88.862-13.954c-12.24,37.21,2.938,71.972-13.954,88.862 c-14.443,14.443-31.824,13.22-43.085,1.959c-6.854-6.854-7.833-18.36-5.875-27.907c-9.547,1.958-20.808,0.979-27.907-5.875 C21.787,266.342,20.563,248.961,35.007,234.519z M118.973,313.833c0-23.99,36.72-37.699,52.877-72.705c17.625,35.006,52.877,48.96,52.877,72.705 c0,20.563-12.975,31.824-29.132,31.824c-9.792,0-18.604-7.344-23.745-15.422c-5.386,8.078-13.953,15.422-23.745,15.422 C131.947,345.657,118.973,334.396,118.973,313.833z M234.519,310.651c-16.892-16.892-0.734-52.633-13.954-88.862c37.21,12.239,71.972-2.938,88.862,13.953 c14.443,14.443,13.22,31.824,1.959,43.085c-6.854,6.854-18.36,7.833-27.907,5.875c1.958,9.547,0.979,20.808-5.875,27.907 C266.342,323.87,248.962,325.094,234.519,310.651z M313.833,226.685c-23.99,0-37.699-36.72-72.705-52.877c35.006-17.626,48.96-52.877,72.705-52.877 c20.563,0,31.824,12.975,31.824,29.131c0,9.792-7.344,18.605-15.422,23.746c8.078,5.386,15.422,13.953,15.422,23.745 C345.657,213.71,334.396,226.685,313.833,226.685z M310.651,111.139c-16.892,16.892-52.633,0.734-88.862,13.954c12.239-37.21-2.938-71.972,13.953-88.862 c14.443-14.443,31.824-13.22,43.085-1.959c6.854,6.854,7.833,18.36,5.875,27.907c9.547-1.958,20.808-0.979,27.907,5.875 C323.87,79.314,325.094,96.695,310.651,111.139z M120.687,31.823c0,23.991,36.72,39.413,52.877,74.42c17.625-35.007,52.876-50.674,52.876-74.42 C226.439,11.261,213.466,0,197.309,0c-9.792,0-18.604,7.344-23.745,15.422C168.178,7.344,159.609,0,149.817,0 C133.661,0,120.687,11.261,120.687,31.823z" /></g></svg>', function (objects, options) {
 fabric.Image.fromURL('http://sharepage.lunastudio.cn/Penguins.jpg', function (img) {
     img.clipTo = function(ctx) {
       objects[0]._render(ctx);
     }
     img.scale(0.1);
     canvas.add(img);
     canvas.renderAll();
 });

 });
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id='canvas' width="400" height="400" style="border:#000 1px solid;"></canvas>

对于全局复合操作是不同的: 您必须在svg(第一个对象)和图像(第二个对象)之间创建一个组,然后将svg的globalCompositeOperation设置为“destination-in”。

答案 1 :(得分:0)

使用较小的图案会使其更快。如果您在代码中更改此内容:

     patternSourceCanvas.setDimensions({
         width: img.getWidth()*0.6,
         height: img.getHeight()*0.6
     });

你会发现它更顺畅。