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.
Related
I have drawn an image on the canvas.
I want the user to click on the canvas to crop a portion of the image.
How can I do this?
Here's an outline to get you started:
Draw the image onto the canvas
var canvas=document.getElementById('myCanvas');
canvas.drawImage(yourImageObject,0,0);
Listen for mousedown events.
canvas.onmousedown=function(e){handleMouseDown(e);};
Have the user click in the top-left [x0,y0] and bottom-right [x1,y1] corners where they want to crop and record those 2 mouse positions.
The cropping rectangle is defined like this:
var x=x0;
var y=y0;
var width=x1-x0;
var height=y1-y0;
Create a second canvas element and size it to the cropping size:
var secondCanvas = document.createElement('canvas');
secondCanvas.width = width;
secondCanvas.height = height;
document.body.appendChile(secondCanvas);
Use the clipping version of drawImage to draw the cropping rectangle from the first canvas onto the second canvas
secondCanvas.drawImage(canvas,
x,y,width,height, // clip just the cropping rectangle from the first canvas
0,0,width,height // draw just the cropped part onto the first canvas
);
The user's selected portion of the image is now on the second canvas.
If you want to convert the second canvas into an image object, you can do this:
var img=new Image();
img.onload=start;
img.src=secondCanvas.toDataURL();
function start(){
// at this point, img contains the cropped portion of the original image
}
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>
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 am using sketch.js http://intridea.github.io/sketch.js/ so users can create drawing in my app. Once they are finished drawing, and click save, I convert the drawing into a png image using this function:
convertCanvasToImage = (canvas) ->
image = new Image()
image.src = canvas.toDataURL("image/png")
image
And then I just append the image to the DOM.
But what if a user wants to edit the drawing afterwards? How can I take that image and add it to the canvas that sketch.js uses?
I tried the following with failed results. When you click the png image I run this code to try to append the image to canvas, but it does not seem to work at all. The canvas is in a modal and once it appears I run the following code to append the image to canvas, but no image appears.
template.$('#sketchModal').on 'shown.bs.modal', (e) ->
c = document.getElementById("sketchPad")
ctx = c.getContext("2d")
ctx.drawImage(e.target, 0, 0)
I haven't used sketch js before, but seeing this code I came with an idea
<div class="tools">
Marker
Eraser
</div>
<canvas id="tools_sketch" width="800" height="300" style="background: url(http://farm1.static.flickr.com/91/239595759_3c3626b24a_b.jpg) no-repeat center center;"></canvas>
<script type="text/javascript">
$(function() {
$('#tools_sketch').sketch({defaultColor: "#ff0"});
});
</script>
You don't want to append the image in canvas but rather add it as a background.
Try it and please inform me if it worked.
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.