自定义图像过滤器中超出最大调用堆栈大小

时间:2015-05-07 22:45:56

标签: javascript fabricjs

我正在寻找一种在FabricJs画布中用图像模式填充图像的方法,因为没有内置的image filter来执行此操作。虽然我的代码仍然处于早期版本,但基本上它应该可以工作(不幸的是它并不是这样); 所有的eavy工作都是通过applyTo方法完成的,我在其中加载图像,然后用图案填充隐藏的画布。我注意到有一个函数(source)属于无限递归:

var pattern = new fabric.Pattern({
   source: function () {
       fhc.setDimensions({
           width: smile.getWidth() + 5,
           height: smile.getHeight() + 5,
       });
       return fhc.getElement();
   },
   repeat: 'repeat'
});

我在JSFiddle

上准备了一个演示

有人可以帮我理解如何解决这个问题吗?

(function (global) {

   'use strict';

   var fabric = global.fabric || (global.fabric = {}),
       extend = fabric.util.object.extend;

   fabric.Image.filters.ImagePatternEffect = fabric.util.createClass(fabric.Image.filters.BaseFilter, {

       type: 'ImagePatternEffect',

       initialize: function (options) {
           options = options || {};

           this.img = options.img;
       },

       applyTo: function (canvasEl) {

           var w = canvasEl.width;
           var h = canvasEl.height;
           var hc = document.createElement('canvas');

           fabric.Image.fromURL('http://i.imgur.com/0Ks0mlY.png', function (smile) {
               debugger;
               hc.setAttribute('width', w);
               hc.setAttribute('height', h);

               var fhc = new fabric.StaticCanvas(hc);
               fhc.add(smile);
               var pattern = new fabric.Pattern({
                   source: function () {
                       fhc.setDimensions({
                           width: smile.getWidth() + 5,
                           height: smile.getHeight() + 5,
                       });
                       return fhc.getElement();
                   },
                   repeat: 'repeat'
               });
               var rect = new fabric.Rect({
                   fill: pattern,
                   width: w,
                   height: h
               });

               fhc.add(rect);
               fhc.renderAll();

               var ifhcContext = fhc.getContext('2d');
               var fhcImageData = ifhcContext.getImageData(0, 0, fhc.width, fhc.height);
               var fhcData = fhcImageData.data;

               var context = canvasEl.getContext('2d'),
                   imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
                   data = imageData.data;

               for (var i = 0, n = data.length; i < n; i += 4) {
                   data[i] += fhcData[i];
                   data[i + 1] += fhcData[i + 1];
                   data[i + 2] += fhcData[i + 2];

               }

               context.putImageData(imageData, 0, 0);

           });

       },

       toObject: function () {
           return extend(this.callSuper('toObject'), {


           });
       }
   });

   fabric.Image.filters.ImagePatternEffect.fromObject = function (object) {
       return new fabric.Image.filters.ImagePatternEffect(object);
   };

})(typeof exports !== 'undefined' ? exports : this);


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


fabric.Image.fromURL('http://i.imgur.com/qaQ8jir.png', function (img) {
   var orImg = img;
   img.filters.push(new fabric.Image.filters.ImagePatternEffect({

       img: orImg,

   }));
   img.applyFilters(canvas.renderAll.bind(canvas));
   canvas.add(img.set({
       width: 300,
       height: 300,

   }));
}, {
   crossOrigin: ''
});

1 个答案:

答案 0 :(得分:0)

我还在我的网络应用程序上使用模式图像,以便将其添加到对象上,并且它可以工作。

所有你需要的是这个函数 function loadPattern(url,seatObj),其中我传递了我想要每次添加模式的对象和图像(模式)链接。

这是片段:

       function loadPattern(url, seatObj) {
    //i use the loadImage function to load the image and pass it to the fabric.Pattern constructor

                    fabric.util.loadImage(url, function (img) {
        //i change the fill property of the object to the
        //image that i want to load on it as a pattern

                        seatObj.fill = new fabric.Pattern({
                            source: img,
                            repeat: 'no-repeat'
                        });
//refresh canvas and watch your image pattern on the object
                        canvas.renderAll();
                    });
                }

希望这有帮助, 祝你好运