Small live preview of FabricJS canvas in another canvas element - javascript

I have an image board utilizing the excellent FabricJS library. I am attempting to create some sort of a "keyhole" view "preview" on another canvas that is on the page, copying a small section of the fabricJS canvas, and displaying it on the second canvas using context.drawImage()
preview_canvas_context.drawImage(fabric.lowerCanvasEl, x,y, ...)
This works great! My issue is ghosting from the copied image. I'm not sure what fancy stuff FabricJS is doing in the background, but if I have some blank space behind an image or object on the fabric canvas, (or I reach the edge of the canvas) the copied image smears as illustrated in the following screen capture:
Why does this happen, and what can I do to fix it?

Setting a background image or color on the canvas prevents this issue from occurring.
var canvas = new fabric.Canvas('c', {
backgroundColor: 'rgb(255,255,255)'
});
I still get image smearing when I leave the outside perimeters, but that is expected and preventable by setting bounds that the viewport object cannot leave.

Related

toDataURL() small screens, small saved image

I have created a web application which uses an HTML5 canvas element to allow users to draw in various shapes, colors, line widths. They can also upload an image, have it drawn onto the canvas and then draw on top of that, as a way to annotate their images.
My challenge is that I am using .toDataURL() to get the entire contents of the canvas saved as an image. As I understand, though, this can only capture the size of the canvas. On smaller devices (phones), the image which is saved, ends up quite small dimensions. Here's what I am doing to get what is on the canvas:
var image = document.getElementById("drawingCanvas").toDataURL("image/jpeg", 1.0);
image = image.replace('data:image/jpeg;base64,', '').replace('data:image/png;base64,', '');
Is there some way to set up my canvas to be able to save larger images, even if the size of the canvas is quite small, due to the device?
Sure...
Save the commands used to create the client's drawing.
Create a larger in-memory canvas with document.createElement.
drawImage a full-sized image to the canvas.
context.scale the canvas.
Re-issue the drawing commands.
Export the enlarged canvas with .toDataURL.
Thanks to context.scale you don't have to change any of the coordinates of the drawing commands.
...and alternatively...
You could eliminate step#1 if you're willing to downgrade the drawings to allow some "jaggies". Do this by using CSS to overlay a canvas on top of the client's img. That way the client's drawings are already isolated on the original canvas. Then your procedure simplifies to:
Create a larger in-memory canvas with document.createElement. Make sure the larger canvas has the same aspect ratio as the original canvas.
drawImage a full-sized image to the canvas.
drawImage the original smaller canvas to the larger canvas. You can use the extended version of drawImage to simultaneously scale the client's drawings: context.drawImage(originalCanvas, 0, 0, originalCanvas.width, originalCanvas.height, 0, 0, largerCanvas.width, largerCanvas.height). Yes, the image source for drawImage can be another canvas. ;-)
Export the enlarged canvas with .toDataURL.

Changing canvas background

I have HTML5 canvas drawing app and I need to change it's background color when user clicks a button.
Background-color on canvas is working on user-side, but user can save the image to server and I'm exporting canvas data using canvas.toDataURL('image/png'). Problem is, background color of canvas is not included, it only sends data user drawn.
I thought about putting big retangle over whole canvas, but that overwrites all drawings already made. Any ideas?
If you want to add the background after you already have drawn something on the canvas, you could add another canvas with the same size and with "display:none" - then, before sending the image, just fill the temporary canvas with your main canvas element's background color from the CSS, then draw the main canvas onto the temporary one.
Finally, send to server the composite from the temporary canvas rather than the bitmap of the main canvas that has the transparent background.
You're not showing any code, but: You need to draw the background using it's context. Setting the background using CSS will as you already discovered not include it when you extract the image.
Canvas is simply put two parts: the canvas element itself and its bitmap. Using CSS affects the element but not the bitmap. Therefor, you need to update the bitmap usually through its context or using the pixel buffer for it to become a part of the bitmap.
Do the following:
At initialization, draw the background using for example fillRect()
Draw your remaining graphics on top
Extract using toDataURL()

How to re-draw a particular portion of canvas?

I'm creating an HTML 5 game using the <canvas> and JavaScript.
In my canvas I'm loading high resolution images. In each Minute there will come some objects to this canvas. If user clicks on it. It'll be removed from the screen.
My issue:
I'm using clearRect() function for clearing the canvas. And again re-draws all images. Is it necessary that each time I re-draw the entire content ? Is there any option to re-draw that particular area ?
When I used the clearRect() to clear the exact area of that object. The background image also got removed. Is there any way to save the particular portion of background image and draw that portion with this saved image ? (Because my objects are moving on the canvas, I need to retreive the image data dynamically)
I'm new to WebTechnology and HTML 5. So please help me. Thanks in advance
There are a few canvas layer libraries that adds support for the layers:
CanvasLayers
CanvasStack
Think of the canvas as a painting, it is not possible to remove a "layer" of content once it has been applied. You can specify a portion of the canvas to clear using clearRect(x,y,height,width), but you will always need to redraw the background of what you deleted. The drawImage() function takes arguments to draw a specific portion of an image in a specific location, but perhaps more along the lines of what you are looking to use is imageData.
I suggest you do some reading up on the canvas here Mozilla Dev Network: Canvas

Image inside canvas crop with custom rectangle JQuery

I have a Canvas element with inside an image ( the canvas has the same dimension of the image), i want to crop this image using a selection rectangle! For my project i use the javascript's framework JQuery and i'm searching a plugin that implementing a custom selection rectangle on canvas!
Anyone know one plugin that do this (I founded a lot of plugin that implements this functionality but only on elements)?
If no, what is the way to implement a custom rectangle on Canvas elements?
I hope in yours answers!
did you tried using Fabric.js to generate rectangle on Canvas ?
Usually, everything that is drawn onto a canvas will automatically change the canvas content. If you want to draw a rectangle with the mouse without destroying the underlying canvas, the usual way is to add an additional (temporary) canvas on top of the original canvas. The new canvas has a transparent background, so the underlying canvas is fully visible.
Now you draw the rectangle on the temporary canvas (which has the same dimensions as the origianl) and store the coordinates of the selection to apply the crop process on the original.
Please see my example here: http://jsbin.com/apitak/4

Why doesn't translate works for the canvas in a div?

I have 2 canvas in a div. I tried to translate one of the canvas, but it didn't work.
http://jsfiddle.net/VkbV5/ shows the case where i commented off the translation line:
this.innerElement2Ctx.translate(100,100);
But when I include the line, the small square disappeared. Why? If you run this page in browser and inspect the innerElement2, you will see that it didn't move at all, but the small square disappeared.
For your information, I need 2 canvas, because I am planning to attach mouse event to innerElement2.
Translating a context adjusts where the 0,0 point is for future drawing commands; scaling a context adjusts how large items draw on the canvas; rotating a context adjusts the direction that items are drawn. None of these context transformations adjust the size or position of the canvas box itself.
Here's an example I made of adjusting canvas transformation so that drawing the same commands allows the user to zoom and pan around a canvas drawing:
http://phrogz.net/tmp/canvas_zoom_to_cursor.html
If you want to move the placement of a canvas within your HTML page, use simple CSS placement as you would with any other element, e.g. a <div>.
If you want complex 2D or 3D transformations you can use cutting edge features of CSS for this (as supported by modern browsers). For example, see:
https://developer.mozilla.org/en/CSS/transform#CSS_transform_functions

Categories

Resources