Skip to content
meltingice edited this page Mar 15, 2011 · 4 revisions

Extending CamanJS

Adding a Filter

Extending CamanJS is very easy. It's accomplished by adding functions onto the manip object. Below is a simple example of how to do so:

Pixelwise Plugin

(function (Caman) {
  // Pixel-wise manipulation
  Caman.manip.fancy_filter = function (adjust) {
// === IMPORTANT ===
// this.process() will be run in a loop, and the
// rgba object represents the current pixel's rgba
// values. you *must* return the modified rgba object
// for it to work properly and you *must* name the function
// passed in the 2nd argument to process() the same name as
// this filter.

return this.process(adjust, function fancy_filter(rgba) {
  rgba.r += adjust;
  rgba.g -= adjust;
  rgba.b += adjust * 2;
  rgba.a = 0.9;
  
  // to get data about a pixel relative to this one currently
  // being processed, you can use getPixel([horiz_offset], [vert_offset]);
  var topLeft      = this.getPixelRelative(-1, 1);
  var topRight    = this.getPixelRelative(1, 1);
  var bottomLeft  = this.getPixelRelative(-1, -1);
  var bottomRight  = this.getPixelRelative(1, -1);
  
  // gets a pixel from the canvas at the specified absolute coordinates
  var absPixel    = this.getPixel(200, 300);
  
  return rgba;
});

}; }(Caman));

Convolution Matrix

(function (Caman) {
  // If you want to use a convolution kernel instead of manipulating each
  // pixel directly, you can easily do it like this:
  Caman.manip.convolutionFilter = function () {
    return this.processKernel('Convolution Filter', [
      [1, 1, 1],
      [1, 1, 1],
      [1, 1, 1]
    ]);
  };
}(Caman));

The arguments to processKernel are:

this.processKernel( Filter Name, Convolution Matrix, [Divisor], [Bias] );

Other Plugins

If you want to add functionality to CamanJS that doesn't fit the pixelwise or convolution matrix patterns, that's totally possible too. A good example of this is the Stack Blur filter that CamanJS uses. Adding a plugin looks like this:

Caman.plugin.myPlugin = function (arg1) {
  // Plugin code goes here.
  // This plugin will be executed with Caman.manip set
  // as the context for 'this', so you have access to all
  // of that information.

  return this;
};

Caman.manip.myPlugin = function (arg1) {
  // Registers the plugin
  // First argument is plugin name, second is array of arguments
  // to be given to plugin when executed in the renderQueue.
  return this.processPlugin("myPlugin", [arg1]);
};

Adding Layer Blending Modes

If you wish to add your own blending mode for layers, simply extend the Caman.manip.blenders object:

(function (Caman) {

// Extend this blenders object
Caman.extend(Caman.manip.blenders, {
  /*
   * This function will be iterated over in a pixel-by-pixel fashion.
   * Both arguments are rgba objects:
   *    rgbaLayer.r, rgbaLayer.g, rgbaLayer.b
   *
   * The first argument is the current pixel from the layer, and the second
   * argument is the current pixel from the parent canvas (the canvas below
   * the current layer).
   */
  someBlender: function (rgbaLayer, rgbaParent) {
    return {
      r: rgbaLayer.r * 2 - rgbaParent.r,
      g: rgbaLayer.g * 1.5 - rgbaParent.g,
      b: rgbaLayer.b * 2.5 - rgbaParent.b
    };
  }
});

}(Caman));

Clone this wiki locally