Clone an HTML canvas and its content - javascript

I have a piece of HTML code with a canvas I'd like to duplicate by the click of a button. I've tried this code so far but I'm a bit clueless about what's missing. If you could include any piece of code it would be really useful to me as I'm a beginner
Thank you
<canvas id="myCanvas" width="800px" height="800px"></canvas>
<script>
var oldCnv = document.getElementById("myCanvas");
function cloneCanvas(oldCanvas) {
//create a new canvas
var newCanvas = document.createElement("canvas");
var context = newCanvas.getContext("2d");
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas, 0, 0);
//return the new canvas
return newCanvas;
//append the new canvas on the page
document.body.appendChild(newCanvas);
}
</script>
<button onclick="cloneCanvas(oldCnv)">add canvas</button>

You can't pass the parameter oldCnv in an onclick action to the function. Besides that, after you return newCanvas the document.body.appendChild(newCanvas) won't get called.
The following will work.
Use this code:
<canvas id="myCanvas" width="800px" height="800px"></canvas>
<script>
var oldCanvas = document.getElementById("myCanvas");
function cloneCanvas() {
//create a new canvas
var newCanvas = document.createElement("canvas");
var context = newCanvas.getContext("2d");
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas, 0, 0);
//return the new canvas
//append the new canvas on the page
document.body.appendChild(newCanvas);
}
</script>
<button onclick="cloneCanvas()">add canvas</button>

Related

Canvas wont display image inside of it

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id="spriteCanvas" width="500" height="500">
<img id="coin" width="440" height="40" src="coin.png">
</canvas>
</body>
</html>
I tried placing an image inside a canvas element, but it won't display on the browser. I know the image tag works because it's displayed if I place it outside of the canvas element. Also, if I inspect the canvas element, I can see that the image is inside, but its dimensions are 0 by 0. Can somebody explain why this isn't working?
EDIT: My original code added the image through javascript, but it wouldn't show on the canvas. It was giving me the same problems as above. But I just realized I was missing "onload".
original code:
var coinImage = new Image();
coinImage.src = "coin.png";
var sCanvas = document.getElementById('spriteCanvas');
function Sprite(canvas, width, height, image){
this.context = canvas.getContext("2d");
this.width = width;
this.height = height;
this.image = image;
}
Sprite.prototype.render = function() {
var that = this;
this.context.drawImage(that.image, 0, 0);
}
function init() {
var coin = new Sprite(sCanvas, 100, 100, coinImage);
coin.render();
}
init();
editted code:
var coinImage = new Image();
coinImage.src = "coin.png";
var sCanvas = document.getElementById('spriteCanvas');
function Sprite(canvas, width, height, image){
this.context = canvas.getContext("2d");
this.width = width;
this.height = height;
this.image = image;
}
Sprite.prototype.render = function() {
var that = this;
this.context.drawImage(that.image, 0, 0);
}
coinImage.onload = function () {
var coin = new Sprite(sCanvas, 100, 100, coinImage);
coin.render();
}
This isn't how a <canvas> tag works. If you want your image to appear in your canvas, you will have to use JavaScript to place the pixels of the image into your canvas.
<canvas>s are exactly what they state: canvases. They are an element for you to draw on programmatically. If you just want to display an image on a page, you don't need a canvas, you just need the <img> tag. In fact, elements should not be placed in <canvas>.
Take a look at CanvasRenderingContext2D.drawImage() and this tutorial: HTML5 Canvas Image Tutorial.
And this snippet:
var canvas = document.getElementById("painting"),
ctx = canvas.getContext("2d"),
image = new Image();
image.onload = function() {
ctx.drawImage(image, 30, 50);
};
image.src = "http://cdn.sstatic.net/Sites/stackoverflow/img/sprites.png?v=10a9e8743fb0";
<canvas id="painting" width="300" height="300"></canvas>
To draw an image on a canvas, use the following method:
drawImage(image,x,y)
If the image you want to draw is not in the DOM already you can load an image directly from a URL with a few lines of javascript.
function loadAndDrawImage(url)
{
// Create an image object. This is not attached to the DOM and is not part of the page.
var image = new Image();
// When the image has loaded, draw it to the canvas
image.onload = function()
{
// draw image...
}
// Now set the source of the image that we want to load
image.src = url;
}
loadAndDrawImage("http://www---.png");

Draw on Image loaded inside HTML canvas

I have a HTML canvas in Ionic app.
<canvas id="canvas" color="{{ color }}" width="800" height="600" style="position:relative;"></canvas>
In this canvas, I am loading an image. Below is the code from controller
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.src = $stateParams.imageId;
img.onload = function() {
context.drawImage(img, 0, 0, canvas.width, canvas.height);
}
After the image is loaded, users need the ability to write on the image and circle/highlight certain areas of the image.
Doesn't HTML canvas provide this feature by default? Right now I am not able to annotate anything on the image. How can I achieve this?
You need to implement this yourself.
You can do it by hooking into the mouse click / move events. using your 2d context, draw small rectangle at the mouse's current position if the most moves and the left mouse button is down.
The effect is similar to a Windows paint pencil tool. Here's a simple example.
<html>
<head>
<style>
canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var isMouseDown = false;
canvas.onmousedown = function(e){
isMouseDown = true;
}
canvas.onmouseup = function(e){
isMouseDown = false;
}
canvas.onmousemove = function(e){
if(isMouseDown === false){
return;
}
var canvasPosition = canvas.getBoundingClientRect();
var x = e.clientX - canvasPosition.left;
var y = e.clientY - canvasPosition.top;
ctx.fillRect(x, y, 2, 2);
};
</script>
</body>
</html>

Clone canvas with fabric js and continue editing

I would like to clone canvas with fabric js and continue editing existing fabric js object in the clone canvas but it is not working. It shows that setBackgroundImage is undefined.
$('#btnClick').on('click touchstart', function () {
var canvas = document.getElementsByTagName("canvas");
// canvas context
var context = canvas[0].getContext("2d");
// get the current ImageData for the canvas
var data = context.getImageData(0, 0, canvas[0].width, canvas[0].height);
// store the current globalCompositeOperation
var compositeOperation = context.globalCompositeOperation;
// set to draw behind current content
context.globalCompositeOperation = "destination-over";
//set background color
context.fillStyle = "#FFFFFF";
// draw background/rectangle on entire canvas
context.fillRect(0,0,canvas[0].width,canvas[0].height);
var tempCanvas = document.createElement("canvas"),
tCtx = tempCanvas.getContext("2d");
tempCanvas.width = 640;
tempCanvas.height = 480;
tempCanvas.setBackgroundImage('');
}
<canvas><canvas>
The idea of using the fabric library is to use its methods to simplify your work. You will not interact with canvas element directly.
The canvas loadFromJSON and toJSON method is what you can use to clone a copy of your canvas including the backgroundimage.
var canvas = new fabric.Canvas('canvas');
var canvas2 = new fabric.Canvas('canvas2');
$(document).ready(function() {
var rect = new fabric.Rect({width: 100, height:200, fill: 'red'});
canvas.add(rect);
var circle = new fabric.Circle({radius: 80, fill: 'blue'});
canvas.add(circle);
$('#clone').click(
function(){canvas2.loadFromJSON(JSON.stringify(canvas), function(){canvas2.renderAll()}); })
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id='canvas' width="500" height="400" style="border:#000 1px solid;">
</canvas>
<input id="clone" type="button" value="clone canvas">
<canvas id='canvas2' width="500" height="400" style="border:#000 1px solid;">
</canvas>

can't add .onclick to image javascript

I want to draw a copy of this image on top of it but further down, but the .onclick isn't working for my image object. I tested it already and it works perfectly fine with canvas.onclick but not with my image 'sticky'.
code is below:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext("2d");
var sticky = new Image();
sticky.src = "sticky.png";
sticky.onload = function() {
context.drawImage(sticky, 0, 0);
};
sticky.onclick = function() {
context.drawImage(sticky, 0, 100);
};
</script>
Your event needs to be on your canvas, not the image. Because when created, an image object isn't automatically added to the dom.
And when a canvas draw an image, it duplicates it, it copies pixels into itself.
So add your image to the dom, and listen for the click on your canvas.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext("2d");
var sticky = new Image();
var sticky2 = new Image();
sticky.src = "http://lorempixel.com/250/60/";
sticky2.src = "http://lorempixel.com/150/60/";
sticky.onload = function() {
context.drawImage(sticky, 0, 0);
};
canvas.onclick = function() {
context.drawImage(sticky2, 0, 100);
};
<canvas id="myCanvas"></canvas>

convert multiple canvases to dataURL in html5

I want to join multiple canvases to make a single image.
So is there any method to covert more than one canvases to toDataURL to make a single image?
create a function that takes multiple arguments (canvas elements), puts them on one blank canvas, then returns the dataurl for the newly made canvas.
var getImadeData = function () {
var i = arguments.length,
tempCanvas = document.createElement("canvas"),
ctx = tempCanvas.getContext("2d");
while (i--) {
ctx.drawImage(arguments[i], 0, 0);
};
return tempCanvas.toDataURL();
};
Now just feed the function multiple canvas elements you want to put into one dataurl like so.
var newData = getImageData(canvas1, canvas2, canvas3);
In this example, the last canvas is placed on the blank canvas first so make sure to order your canvas elements appropriately.
Yes, the drawImage method on the canvas 2d rendering context accepts canvas elements as image elements. So all you have to do is:
Create a new canvas
Get its context
Draw all other canvases to it with drawImage
Extract the final image from this new canvas
try this example hope it will help see here
//html block
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
</canvas>
<canvas id="myCanvas1" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<canvas id="Canvasimage" width="500" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<img id="finalimage" width="500" height="100" style="border:1px solid #c3c3c3;"/>
//script block
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for (var src in sources) {
numImages++;
}
for (var src in sources) {
images[src] = new Image();
images[src].onload = function () {
if (++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
window.onload = function (images) {
//Canvas first here
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 200, 100);
//Canvas second here
var c1 = document.getElementById("myCanvas1");
var ctx1 = c1.getContext("2d");
ctx1.fillStyle = "#00FF00";
ctx1.fillRect(0, 0, 200, 100);
//Canvas final here.
var canvas = document.getElementById("Canvasimage");
var context = canvas.getContext("2d");
var sources = {
darthVader: c.toDataURL("image/png"),
yoda: c1.toDataURL("image/png")
};
loadImages(sources, function (images) {
context.drawImage(images.darthVader, 100, 30, 200, 137);
context.drawImage(images.yoda, 350, 55, 93, 104);
//finalimage here which has two canvas data
var finalimage = document.getElementById("finalimage");
finalimage.src = canvas.toDataURL("image/png");
});
};

Categories

Resources