Nauman
Nauman

Reputation: 118

Mask Image based on another image

I have urls of two images(png). I need to load them and mask one image based on another. I am using fabricjs library. But I am unable to achieve the desired result so far. My question is that Is it doable using fabricjs? If yes, please point me in the right direction and give some hint.

Thanks.

Upvotes: 1

Views: 1308

Answers (1)

Khawer Zeshan
Khawer Zeshan

Reputation: 9646

I don't think it is possible to use image as a mask in fabricjs. However it is possible to use SVG as a mask either from SVG String or SVG URL. Here is an example to use SVG as a mask using SVG string.

$(document).ready(function () {
    var imageLoader = document.getElementById('imageLoader');
    imageLoader.addEventListener('change', handleImage, false);
});

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

var group = [];

fabric.loadSVGFromString('<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg"><title>Black Shirt</title><metadata id="metadata69503">image/svg+xml</metadata><g><title>Layer 1</title><g id="layer1"><path id="path3287" d="m166.18439,17.37708c-2.03961,0.05794 -4.09917,0.64444 -5.99701,1.79727l-121.55794,73.83949c-6.07317,3.68897 -8.13302,11.78955 -4.62673,18.17904l41.40907,75.46835c3.50636,6.3895 11.22366,8.55663 17.29683,4.86769l63.52823,-38.58598l0,282.00912c0,7.37784 5.65755,13.33011 12.67012,13.33011l234.68106,0c7.0127,0 12.65225,-5.95227 12.65225,-13.33011l0,-282.40228l64.18686,38.97914c6.073,3.68893 13.77252,1.5218 17.27887,-4.86769l41.40912,-75.46835c3.50623,-6.38949 1.44635,-14.49007 -4.62665,-18.17904l-121.54025,-73.83949c-2.46729,-1.49862 -5.21344,-2.02985 -7.82983,-1.70369c-0.50259,-0.0633 -1.01096,-0.09358 -1.53036,-0.09358l-67.22971,0c-0.99521,8.39134 -22.93723,15.10861 -49.80826,15.10861c-26.87125,0 -48.79539,-6.71727 -49.79056,-15.10861l-67.85254,0c-0.40805,0 -0.81207,0.03552 -1.21001,0.07484c-0.50517,-0.05004 -1.00247,-0.08936 -1.51256,-0.07484z" stroke-miterlimit="4" stroke-width="4.468" stroke="#000000" fill="#000000"/></g></g></svg>',function(objects,options) {
    var loadedObjects = new fabric.Group(group);
    loadedObjects.set({
        scaleX:0.5,
        scaleY:0.5,
        lockMovementX : true,
        lockMovementY : true,
        lockScalingX : true,
        lockScalingY : true,
        lockUniScaling : true,
        lockRotation : true,
        selectable: false,
        hasRotatingPoint:false,
        hasControls: false,
        hasBorders: false
    });

    canvas.add(loadedObjects).centerObject(loadedObjects).renderAll();
},function(item, object) {
    object.set('id',item.getAttribute('id'));
    group.push(object);
});

function handleImage(e) {
    var reader = new FileReader();
    //comment out the below code if you want to remove the previous uploaded image
    /*if(canvas.item(1)){
        canvas.remove(canvas.item(1))
    }*/
    reader.onload = function (event) {
        var img = new Image();
        img.onload = function () {
            var imgInstance = new fabric.Image(img, {
                width:200,
                height:200,
                lockMovementX : false,
                lockMovementY : false,
                lockScalingX : false,
                lockScalingY : false,
                lockUniScaling : false,
                lockRotation : false,
                selectable: true,
                hasRotatingPoint:true,
                borderColor: 'red',
                cornerColor: 'green',
                hasControls: true,
                hasBorders: true,
                transparentCorners: false
            });

            canvas.add(imgInstance).centerObject(imgInstance).renderAll();
            canvas.setActiveObject(canvas.item(1));

            var shape = canvas.item(0);
            canvas.clipTo = function(ctx) {
                shape.render(ctx);
            };

            canvas.controlsAboveOverlay = true;
            canvas.renderAll();
        };
        img.src = event.target.result;
    };
    reader.readAsDataURL(e.target.files[0]);
}

There is also one limitation for SVG. If SVG has multiple paths it will only mask the last path. I couldn't find the solution to make it work for all paths of SVG.

FIDDLE

Upvotes: 4

Related Questions