Adding background to transparent image - javascript

I need to export my chart created in canvas as image file. I managed to do it but the image is transparent (no background). My question is, is there a way with code to add background color to existing image i got from canvas?
Example:
Canvas in browser:
Canvas when exported as .png:

You have several ways to accomplish your task.
By far the easiest is to fill the entire canvas with a background color before starting to draw your chart. Hint: you don't show code, but do this easy solution if possible. ;=)
context.fillStyle='white';
context.fillRect(0,0,canvas.width,canvas.height)
If you can't fill-before-starting, you still have some options.
You can save the chart to another canvas, fill the entire main canvas with background color and then redraw the saved chart back onto the main canvas.
// create a second canvas and draw the chart onto it
var secondCanvas=document.createElement('canvas');
var cctx=secondCanvas.getContext('2d');
secondCanvas.width=canvas.width;
secondCanvas.height=canvas.height;
cctx.drawImage(mainCanvas,0,0);
// fill the main canvas with a background
context.fillStyle='white';
context.fillRect(0,0,canvas.width,canvas.height)
// redraw the saved chart back to the main canvas
context.drawImage(secondCanvas,0,0);
You can use compositing to cause new drawings to be drawn behind existing pixels. The draw the entire background and it will appear behind the existing chart.
// set compositing to draw all new pixels (background) UNDER
// the existing chart pixels
context.globalCompositeOperation='destination-over';
// fill the main canvas with a background
context.fillStyle='white';
context.fillRect(0,0,canvas.width,canvas.height)
// always clean up ... reset compositing to default
context.globalCompositeOperation='source-over';

There is no need to use JavaScript, just give the image a background color using CSS.
<style>
img {
background-color: black;
}
</style>
<img src="...">
See this JSFiddle for another example: https://jsfiddle.net/3jch7z94/1/

Related

Apply frame image on top of Fabric JS Canvas

I am using Fabric JS to allow the user to have an interactive experience on my React app. Is it possible to apply a frame around a Fabric JS that is taken from an image? For instance, if the canvas is 400x400 px I can resize an image of a frame that is transparent in the middle to 410x410px and apply it on top of the canvas for the user to see? I have attached two images for reference.
Edit: This is the code I am using for zooming in
const zoomIn = useCallback(() => {
// Get original height of canvas
const canvasDimensions = getInitialCanvasSize()
let zoom = HTML5Canvas.getZoom()
zoom += 0.2
if (zoom >= 2) zoom = 2
HTML5Canvas.setZoom(zoom)
HTML5Canvas.setWidth(canvasDimensions.width * HTML5Canvas.getZoom());
HTML5Canvas.setHeight(canvasDimensions.height * HTML5Canvas.getZoom());
}, [HTML5Canvas])
There is no option for canvas's border in fabricjs canvas docs
But you can still achieve this easily using following steps.
PART 1: Creating the Illusion of border
CSS Method
First one can easily create CSS border around the canvas.
Best way to do this is to create div around canvas, as fabricjs split canvas in 2 while running.
You can create slider to control width and color/image for div's border.
This will looks like exactly your second image with customization.
OR
Another Canvas Method
Behind current canvas put this second canvas and control its width and image.
I don't recommend this one, as this will make it more complex to implement.
PART 2: Making Illusion real
If you used CSS METHOD
Now you get what your canvas looks like. You have width of border, image/color of border.
Steps:
Create new canvas (lets' call it 2nd Canvas) of 410px if canvas's width 400px with border of 5px.
Export main canvas as image and put it over 2nd Canvas. And now you can export this as final image.
For 2nd step check my answer on this stack
If you used Another Canvas Method
Directly follow above 2nd step
Export main canvas as image and put it over 2nd Canvas. And now you can export this as final image.
For 2nd step check my answer on this stack

Using canvas to layer animated and static content

I would like to have the fireworks from https://codepen.io/haidang/pen/WRGXJv overlaying the interactive table+button from https://codepen.io/kimaro/pen/BjqYeo.
I have tried using two canvases, where the canvas for the fireworks has
z-index=1
and the canvas for the table+button has
z-index=0
I tried changing the following in fireworks.js:
ctx.fillStyle = '#000'; //old
ctx.fillstyle = 'rgba(0,0,0,0)' //full transparent background
however the table+button canvas doesn't show for me. additionally, when changing the fillstyles for fillrect methods to be transparent, the background of the firework canvas changes colour randomly.
Additionally, if I call the firework js at the end of my html, then I can't click on the button of the canvas layer underneath.
Edit: As has been pointed out by Archer, the button would have to be on the top canvas layer. In this case, the background of the table+button layer would have to be transparent, whilst the layer underneath has the desired background colour.
Edit 2: A friend suggested I could merge the layers, to overcome the issue of the button being on the layer below.

How to clear rectangle on Image in 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.

Add more space to existing canvas without redrawing?

I've created a canvas that I've drawn images and texts on. Is it possible to add more space (height in my case) to the current canvas without having to redraw everything? I would like to add text below the already drawn items but to do this I have to add more height to canvas.
Or can I do it the other way around - create a too large canvas to start with and then add all my texts and in the end crop the canvas (removing white unused space)?
I like recursive's idea using a container that you first size short and then expand to reveal the extra canvas space needed to draw text.
Another common way of resizing a canvas is to bounce the canvas contents off a temporary canvas.
// create a temp canvas (no need to add it to the DOM)
var tempCanvas=document.createElement('canvas');
var tempCtx=tempCanvas.getContext('2d');
tempCanvas.width=mainCanvas.width;
tempCanvas.height=mainCanvas.height;
// draw the main canvas to the temp canvas
tempCtx.drawImage(mainCanvas,0,0);
// resize the main canvas
mainCanvas.height+=30;
// restore the main canvas content by drawing the temp canvas
mainCtx.drawImage(tempCanvas,0,0);
You could put your canvas inside a container with a fixed target height. If you set its overflow to hidden, then you can control how much can be seen.
Changing the dimensions of a canvas clear it, so that won't work.

Possible to Export KineticJS Complete Layer

Does anybody know if there is a way to 'export' an entire KineticJS layer (or group) and not just the part that is in the visible canvas?
I have a simple 'image editor' that allows the user to scale the image in the canvas, the image can deliberately be scaled larger than the visible canvas stage area allowing the user to pan the image sections into view. The problem is that when they come to export the image (currently using the toDataURL) only the section of the image in the visible canvas stage is saved, the rest of the image is discarded!
I effectively want to save the whole layer, not just what is rendered in the visible canvas stage.
Well, You need a temporary workaround.
I assume you have a function or something that does .toDataURL().
Right before you do toDataURL(), change the stage size or scale, then save, then change back.
Example:
function save(){
stage.setScale(newX,newY); //rescale to new values
stage.setWidth(newWidth);
stage.setHeight(newHeight);
stage.toDataURL(); // <----- save
stage.setScale(oldX,oldY); //rescale to old values
stage.setWidth(oldWidth);
stage.setHeight(oldHeight);
}
This will resize or rescale your stage and then put it back the way it was.

Categories