1

I want to store all the filters applied by different buttons and then apply then sequentially on an image. For example, if a user clicks on Brigthness, Noise, Contrast. I want to store these filters and once a user clicks on Apply Filters. I want to apply them all. I tried the following method:

Caman('#canvas', img, function () {
     //this.brightness(10).render();
     var filters = ["brightness(10)", "noise(20)"];
     filters.forEach(function (item, index) {
          this.filters(item);
     });
     this.render();
});

But this gives me the error this.filters is not a function. I can use the commented out line but that will only apply predetermined filters. I want to apply filters based on user selection and I want to apply them all at once when user clicks on apply filters.

Here is a link to the library: http://camanjs.com/examples/

Can anyone please guide me how can I achieve what I want? Let me know if I did not explain the question clearly before downvoting.

Neena Vivek
  • 667
  • 7
  • 19

3 Answers3

0

That error is showing up because when you use this inside foreach the value of this points the filter array and not caman object Try this

Caman('#canvas', img, function () {
     //this.brightness(10).render();
     var that = this;
     var filters = ["brightness(10)", "noise(20)"];
     filters.forEach(function (item, index) {
        eval('that.'+item); 
     });
     this.render();
});

In above code a copy of this is made which is then passes to inside the loop with name as that

Vinay
  • 7,442
  • 6
  • 25
  • 48
  • Thanks Novice, this seems to be the easiest method for applying the filters. Are there any disadvantages of this method compared to other answers? – Neena Vivek Dec 11 '16 at 10:27
  • 1
    No disadvantage , although you shouldn't use eval in common cases but it's perfectly fine in frontend cases when you want to make dynamic function calls without compromising code succinctness in a small snippet – Vinay Dec 11 '16 at 12:03
  • @NeenaVivek Please read http://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea – SLePort Dec 11 '16 at 17:49
0

this.filters won't work because 'this' refers to the scope of function(item, index) {...}

I would do something like this:

Caman('#canvas', img, function () {
     // make 'this' available in the scope through 'self' variable
     var self = this;      

     // Filters must hold the function and not a string of the function.
     // so something like:
     var filters = [
       function() { self.brightness(10); },
       function() { self.noise(20); }
     ];

     filters.forEach(function (fn) {
          fn(); // this will execute the anonymous functions in the filters array
     });

     this.render();
});
aaa
  • 601
  • 6
  • 13
0

You can define objects in your array and loop over the effects using forEach():

Caman('#canvas', img, function () {
  var filters = [
    { name: "brightness", val:10 },
    { name: "noise", val:20 }
  ];
  var that = this;
  filters.forEach(function(effect) {
    that[effect.name](effect.val);
  });
  this.render();
});
SLePort
  • 15,211
  • 3
  • 34
  • 44
  • When I tried this method, I got the error `Uncaught TypeError: that[effect.name] is not a function`. I tried adding a `.` after `that` but then I got an error about unexpected `[`. – Neena Vivek Dec 12 '16 at 13:08
  • Make sure `effect` (`item` variable renamed) is passed as parameter to the anonymous function. Or make a jsfiddle with testable code. – SLePort Dec 12 '16 at 13:24