The title say it all. You can see Fabric.js Mask Filter Demo. This should be pretty simple but I can't find any example of applying mask to Fabric.js.
I am trying to apply mask to my JSFiddle. http://jsfiddle.net/ZxYCP/342/
From my JSFiddle, my goal is to have both logo and pugImg clipped inside this picture (or any picture if you want). Well, I can't even mask one picture anyway, so if this is not bothering you, please update the JSFiddle for better explanation.
In addition, the code from #kangax, creator of Fabric.js <3, in this question should be the solution but I can't manage to work. The result should be like the image below. Any further suggestion is appreciated.
You are not really trying ot mask an image. You are using some compositing effects.
There are a couple of things to understand that are not directly related to fabric.js.
A mask goes over an image.
The demo link you posted will not make you get the effect as in the screenshot.
If this is the case, you should have:
a light blue canvas
a pug.jpg image
a white overlay image with a girl-shaped transparent hole in it
Make a sandwich with those 3.
In this case you are masking the canvas not the image.
If you have a girl-shaped path, you can clip the canvas as seen in:
Fabric.js Clip Canvas (or object group) To Polygon
But you state that you want to use a image instead.
So if you do not have the overlay with girl-shaped hole, you can use another solution to get the same effect:
a transparent canvas
a light blu image with a shape you need and transparent pixels all around
a pug.jpg image
Add the first image on the canvas;
set the globalCompositeOperation of the pug.jpg to 'source-atop'
paint the other image over the other
var canvas = new fabric.Canvas('c');
fabric.Image.fromURL('http://fabricjs.com/assets/2.svg', function(img){
img1 = img;
fabric.Image.fromURL('http://fabricjs.com/assets/pug.jpg', function(img){
img1.scaleToWidth(canvas.getWidth());
img2 = img;
img2.scaleToHeight(300);
img2.left = 50;
img2.top = 50;
img2.globalCompositeOperation = 'source-atop';
canvas.add(img1);
canvas.add(img2);
});
});
<script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>
Related
I'm writing an application that needs static clipping for images on the canvas (as you move the images on the canvas the clipping area stays in one place). I have three cases: polygon, ellipse, any shape specified with an image. I was able to cope with polygon and ellipse, because I can do them with paths and arcs, but when it comes to a mask specified via an image I'm not sure what to do.
Example shape to clip to:
Let's say I am not able to draw it using paths
So I have it specified with an image, I know how to obtain image data from it. What I'm trying to achieve is to clip everything that is out of that figure.
I was trying like this:
canvas.clipTo = function (ctx) {
ctx.drawImage(shape.src, left, top);
};
And like this:
canvas.clipTo = function (ctx) {
ctx.putImageData(imgData, left, top);
};
Of course none of them work as I expect, it just draws that black shape instead of clipping to that region.
Any ideas how to do it?
I do it by creating a new canvas the same size as the mask image. Then draw the image on that canvas, then set the ctx.globalCompositeOperation to "destination-in" draw the mask over the image (masking it) , then draw the that canvas to the on-screen canvas with ctx.drawImage
As this is most definitely a duplicated question I will not give the answer as code, it's been done to death here on stackoverflow.
Oh and I forgot. Using imageData to clip is a very inefficient way to do it.
The title say it all. You can see Fabric.js Mask Filter Demo. This should be pretty simple but I can't find any example of applying mask to Fabric.js.
I am trying to apply mask to my JSFiddle. http://jsfiddle.net/ZxYCP/342/
From my JSFiddle, my goal is to have both logo and pugImg clipped inside this picture (or any picture if you want). Well, I can't even mask one picture anyway, so if this is not bothering you, please update the JSFiddle for better explanation.
In addition, the code from #kangax, creator of Fabric.js <3, in this question should be the solution but I can't manage to work. The result should be like the image below. Any further suggestion is appreciated.
You are not really trying ot mask an image. You are using some compositing effects.
There are a couple of things to understand that are not directly related to fabric.js.
A mask goes over an image.
The demo link you posted will not make you get the effect as in the screenshot.
If this is the case, you should have:
a light blue canvas
a pug.jpg image
a white overlay image with a girl-shaped transparent hole in it
Make a sandwich with those 3.
In this case you are masking the canvas not the image.
If you have a girl-shaped path, you can clip the canvas as seen in:
Fabric.js Clip Canvas (or object group) To Polygon
But you state that you want to use a image instead.
So if you do not have the overlay with girl-shaped hole, you can use another solution to get the same effect:
a transparent canvas
a light blu image with a shape you need and transparent pixels all around
a pug.jpg image
Add the first image on the canvas;
set the globalCompositeOperation of the pug.jpg to 'source-atop'
paint the other image over the other
var canvas = new fabric.Canvas('c');
fabric.Image.fromURL('http://fabricjs.com/assets/2.svg', function(img){
img1 = img;
fabric.Image.fromURL('http://fabricjs.com/assets/pug.jpg', function(img){
img1.scaleToWidth(canvas.getWidth());
img2 = img;
img2.scaleToHeight(300);
img2.left = 50;
img2.top = 50;
img2.globalCompositeOperation = 'source-atop';
canvas.add(img1);
canvas.add(img2);
});
});
<script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>
I need to clear a rectangle Drawn on Image in Canvas with out damage existing image. I can draw small rectangle points and clear that out. But the problem is when I clear rectangle it remains as white small patch on image.
Can someone tell me how to clear a rectangle on image without damage the existing image.
I have used following methods to clear rectangles but didn't work.
1) context.fillStyle ="white";
2) context.clearRect(xCoordinate, yCoordinate, 10, 08);
Thanks in advance!
Canvas doesn't work that way. It's a single layer, its also transparent by default. So with that in mind, you might be able to achieve what you want by simply giving the canvas element a CSS background. That way anything you draw on top of that background can easily be removed and the background will show through.
#backed-canvas{
background-image: url(http://www.placebear.com/300/200);
}
JSFiddle example: https://jsfiddle.net/yLf5erut/
There is one thing you can do.
When create a rectangle on the canvas just get the image data like:
var imgData = context.getImageData(xCoordinate, yCoordinate, 10, 8);
and draw the rectangle.
When clearing out the rectangle just place then image data back like this:
context.putImageData(imgData, xCoordinate, yCoordinate);
I suggest using 2 canvas elements one over another.
So you can have the original image drawn on the bottom canvas with low zIndex, and the top one with highter zIndex can be used to draw / clear whatever needed. This is a common practice, and for more complecated animations you will end up with better performance.
I have a canvas element that I'm setting the background on dynamically via code. Then I'm using the Sketch library (http://intridea.github.io/sketch.js/) to draw on the canvas. - This all works.
However, whenever I try to convert the canvas using canvas.toDataURL("image/png") it's able to save the canvas drawing, however isn't saving the background. - I understand this is working as designed.
Is there a way to merge the two? I was toying around with the idea that I could set the image src to the background src after I'm done drawing and try to export that, however I'm not certain. Does anyone have any experience with this?
As you've discovered, the canvas and its background are maintained separately and toDataURL will not also capture the background.
You can combine the background with the sketch using canvas compositing.
The 'destination-over' compositing mode will let you drawImage your background behind the sketches
context.globalCompositeOperation="destination-over";
context.drawImage(backgroundImage,0,0);
Now the background pixels have been drawn behind you sketch and both will be captured with toDataURL.
Yes, You are correct. I fetch the background image along with canvas image and download.
ctx.width = 2503;
ctx.height = 250;
ctx.globalCompositeOperation="destination-over";
var background = new Image();
background.src = "http://localhost/xxxxx/xxxxx/xxxxx/xxxxx/ecg_back.png";
ctx.drawImage(background, 0, 0);
// create pattern
var ptrn = ctx.createPattern(background, 'repeat'); // Create a pattern with this image, and set it to "repeat".
ctx.fillStyle = ptrn;
ctx.fillRect(0, 0, ctx.width, ctx.height);
How are you adding the background to the canvas? Are you setting it in css as a background image? Or are you adding the image directly to the canvas? I think you'll need to do the latter, as per the example here.
I want to draw an image to canvas and then allow user to draw some sketch on it by sketch.js. Now the situation is:
1.the image has been drawn on the canvas successfully
2. but when my mouse over the canvas, then image disappeared, and the canvas shows empty
3. when I dragged the mouse, some sketch shows on the empty canvas(the sketch looks correct)
so, I've made both functions right, but I'm confused about the part in between. I hope to draw the sketch on the canvas with the image on it. Here is my code:
index.html:
<canvas id="mysketch" width="578" height="400" style="margin: 0px; "></canvas>
canvas.js:
var mysketch = jQuery("#mysketch");
// draw the captured image to canvas
var displayImage = function() {
var context = mysketch.get(0).getContext("2d");
var image = new Image();
image.onload = function() {
context.drawImage(image, 0, 0);
}
// prepend the required image info again
image.src = dataURL;
// call sketch.js to draw sketch on the canvas
mysketch.sketch({defaultColor: "#ff0"});
}
I think that, on your call to sketch method
sketch.js is clearing the canvas first then allows you to draw something on it.
As you can see in the link here, in the 3rd example (i.e. Tools Example) the image is not drawn by drawImage method.
It is actually the background of the canvas which will always be there as background, whatever you draw on it.
So what you can do is:
either do same thing as in the example i.e. set your image as background,
or make a new canvas just behind your canvas with same width, height and on same location and draw your image on it. and do your sketch thing on the second one.