0

Is it possible to mask two images using fabric js?

For example: I have a colored shape(heart). I have another images and I want to mask it over heart such that that new image is only displayed as heart. I can move the second uploaded image around and resize to get the desired area in that heart.

Both images are user uploaded images and not one of those rectangles or square which are created using fabric and drag and resize image like in the jsfiddle example here.

http://jsfiddle.net/Jagi/efmbrm4v/1/

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

var clippingRect = new fabric.Rect({
    left: 0,
    top: 0,
    width: 100,
    height: 100,
    fill: 'transparent',
    opacity: 1
});
canvas.add(clippingRect);

function handleImage(e) {
    var reader = new FileReader();
    reader.onload = function (event) {
        var img = new Image();
        img.onload = function () {

            var instanceWidth, instanceHeight;

            instanceWidth = img.width;
            instanceHeight = img.height;

            var imgInstance = new fabric.Image(img, {
                width: instanceWidth,
                height: instanceHeight,
                top: (canvas.getHeight() / 2 - instanceHeight / 2),
                left: (canvas.getWidth() / 2 - instanceWidth / 2),
                originX: 'left',
                originY: 'top'
            });
            canvas.add(imgInstance);
            imgInstance.clipTo = function (ctx) {
  ctx.save();
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.rect(
    100, 100,
    200, 200
  );
  ctx.restore();
            };
            canvas.renderAll();
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(e.target.files[0]);
}

I need exactly this but with two custom images(user uploaded images).

Nauman
  • 118
  • 1
  • 13

1 Answers1

0

Maybe this pseudo example will give you pointer how to add mask with a path, not just a rectangle.

//adding main image and mask
fabric.Image.fromURL(IMAGE_URL_HERE, function(pic) {
  canvas.add(pic);
  //positioning image, if needed
  pic.centerH().setCoords();

  //adding path, may be a heart or any other in your case
  var path = new fabric.Path('M1.398,84.129c3.305,20.461,9.73,50.635,13.591,67.385c2.354,10.212,12.549,23.734,18.51,30.02c4.923,5.191,27.513,23.343,38.34,27.589c18.604,7.295,33.984,4.187,46.012-8.306c12.028-12.493,25.595-34.78,27.954-43.994c2.587-10.105,5.065-26.842,4.313-37.243c-1.036-14.316-14.224-69.332-16.806-79.55c-4.48-17.735-26.246-48.821-80.609-37.668C-1.66,13.514-1.879,63.844,1.398,84.129z');

//positioning path, if needed
path.set({
  originX: 'center',
  originY: 'center',
});

//masking img with path
pic.set({
  clipTo: function(ctx) {
    path.render(ctx);
  }
});

  canvas.renderAll();
});

Full demo (for slightly another case though) here: http://jsfiddle.net/mqL55m0f/2/

shershen
  • 9,875
  • 11
  • 39
  • 60