API Docs

Custom Operations

Adding Custom Operations

Per default, the SDK just renders the plain image. To modify the rendered image you need to add “operations” to it. There are a bunch of operations that you can use.

Operations can be configured by passing an options hash to them. Let’s create a FilterOperation and pass the FridgeFilter to it.

const sdk = /* ... (see previous section) */
const filterOperation = new PhotoEditorSDK.Operations.FilterOperation(sdk, {
  filter: new PhotoEditorSDK.Filters.FridgeFilter()

The canvas should now display your image with a filter on it.

The available options of each operation are documented in our API Documentation. We also created [a lot of beautiful filters](API Documentation: PhotoEditorSDK.Filters that you can use.

Extending operations

By extending the Operation class you can add custom image modifications to the SDK.

Rendering workflow

The SDK draws the image to the output canvas by rendering a Sprite instance. Before that, it applies all existing operations to that sprite.

An operation has an internal sprite which it uses to render the modified image to an internal texture. This texture is then added to the output sprite so that the SDK can render the resulting image to the output.


The Operation class implements two protected methods that handle the rendering: _renderWebGL, which is called whenever the operation is applied using the WebGLRenderer, and _renderCanvas which is called when it’s applied using the CanvasRenderer. If those two methods are doing the same, you can just override the generic _render method.

Let’s create a FlipOperation which flips the image on the X axis.

class FlipOperation extends PhotoEditorSDK.Operation {
   * Renders this operation
  _render (inputTexture) {
    // Flip the sprite on the X-axis
    this._sprite.setScale(-1, 1)

    // Make sure we flip around the center
    this._sprite.setAnchor(0.5, 0.5)
    this._sprite.setPosition(renderTexture.getWidth() / 2, renderTexture.getHeight() / 2)

    // Render the flipped image to the render texture

    // Let the SDK render the flipped image (or let the next
    // operation use the flipped image as input). You can't
    // render Sprite instances directly, so we're gonna use
    // the container instead.

    // Since we're not doing anything asynchronous, let's just
    // return an already resolved Promise
    return Promise.resolve()

 * A unique string that identifies this operation
FlipOperation.identifier = 'flip'

Now you can instantiate and add the operation as mentioned above. (“Adding operations”)

Adding options

To make your operation configurable, you can add an availableOptions object:

FlipOperation.prototype.availableOptions = {
  flipHorizontally: { type: PhotoEditorSDK.OptionTypes.BOOLEAN, default: false },
  flipVertically: { type: PhotoEditorSDK.OptionTypes.BOOLEAN, default: false }

You can now access the options using this._options:

  this._options.flipHorizontally ? -1 : 1,
  this._options.flipVertically ? -1 : 1

This also adds the getFlipHorizontally()/setFlipHorizontally() and getFlipVertically()/setFlipVertically() methods to your operation.