Christopher Marshall
Christopher Marshall

Reputation: 10736

Fabric.js: How to apply filter to entire canvas?

While I've seen several methods to apply filters to images, I have yet to see anything that would apply the fabric filter to the entire canvas.

Example of image filter function from http://fabricjs.com/fabric-intro-part-2/

fabric.Image.fromURL('pug.jpg', function(img) {

  // add filter
  img.filters.push(new fabric.Image.filters.Grayscale());

  // apply filters and re-render canvas when done
  img.applyFilters(canvas.renderAll.bind(canvas));

  // add image onto canvas
  canvas.add(img);
});

I want to pass in the entire canvas element and all the shapes inside and apply the filter to all.

Do I need to flatten the canvas, convert it to an image, and then apply the filter? The user may make changes afterwards to after flatten and apply, the canvas would have to be decoupled back to 'layers' so the user could continue to edit.

Docs for GreyScale filter. http://fabricjs.com/docs/symbols/fabric.Image.filters.Grayscale.html

Upvotes: 1

Views: 4807

Answers (1)

Christopher Marshall
Christopher Marshall

Reputation: 10736

Ended up having to convert canvas to image then added it from a hidden image in the html.

<img class="test-image" src="" style="display:none;" /> in markup

var addFilterToCanvas = function (name) {

    // remove controls on filter click, have to do it before it creates the image to
    // get rid of shape controls
    canvas.deactivateAll()

    var overlayImageUrl = canvas.toDataURL('png');
    $('.test-image').attr('src', overlayImageUrl);
    var filterImageUrl = $('.test-image').attr('src');


            fabric.Image.fromURL(filterImageUrl, function(img) {

            // add filter
            switch (name) {
                case 'Grayscale':
                    img.filters.push(new fabric.Image.filters.Grayscale());
                break;
                case 'Sepia':
                    img.filters.push(new fabric.Image.filters.Sepia());
                break;
                case 'Sepia2':
                    img.filters.push(new fabric.Image.filters.Sepia2());
                break;
                case 'Invert':
                    img.filters.push(new fabric.Image.filters.Invert());
                break;
            }

                // apply filters and re-render canvas when done
                img.applyFilters(canvas.renderAll.bind(canvas));

                // center image 
                img.top = canvas.getHeight() / 2;
                img.left = canvas.getWidth() / 2;

                // add image onto canvas
                canvas.add(img);
            });

        // remove controls on after filter applied to get rid of
        // new image resize controls
        canvas.deactivateAll().renderAll();

}

Upvotes: 1

Related Questions