Can you clone contents of an element into canvas? - javascript

I was wondering if it's possible to clone an HTML element into canvas. So looking at this JSFiddle, how would you duplicate it into canvas?
I've seen ways to draw DOM objects into a canvas element, but I was curious if there was a way to do it differently.
<p>Html</p>
<div id="clone-me">
<div id="square">
</div>
</div>
<p>Canvas</p>
<canvas width="200" height="200"></canvas>
#clone-me {
width: 200px;
height: 200px;
background: #333;
}
#square {
width: 70px;
height: 70px;
background: red;
}

You can use html2canvas to do it, you can checkout the demo at this JSFiddle.
html2canvas(document.getElementById('clone-me'), {
onrendered: function(canvas) {
var canvas1 = document.getElementById('canvas1');
var ctx = canvas1.getContext('2d');
ctx.drawImage(canvas, 0, 0);
}
});

Related

Placing two canvas elements on top of each other

I know this has been asked a few times already on SO (e.g.here), but I don't seem to be able to get this to work.
I'm trying to:
display images
place a canvas on top of each of them
get a user to draw on the top canvas based on the image underneath
get the data off all canvases to be stored locally.
I haven't been able to get the CSS to work so that the canvases are on top of each other and I've tried several ways of doing it.
HTML:
<div class="row">
<div class="pb-2 justify-content-center">
<h2><strong>Drawing test</strong></h2>
<div class="justify-content-center">
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
<div class="wrapper">
<canvas id="dorsal" height="512" width="512"></canvas>
<canvas id="dorsal-duplicate" height="512" width="512"></canvas>
</div>
</form>
</div>
</div>
CSS
canvas {
position: absolute;
top: 0;
left: 0;
}
.wrapper {
position: relative;
width: 512px;
height: 512px;
}
.wrapper canvas {
position: absolute;
top: 0;
left: 0;
}
JS
var canvas1 = document.getElementById("dorsal"), ctx1 = canvas1.getContext("2d");
var canvas2 = document.getElementById("dorsal-duplicate"), ctx2 = canvas2.getContext("2d");
var background1 = new Image();
var to_draw_on = new Image();
background1.src = "{% static aspects.Dorsal.0 %}"; /* image from Django static folder */
background1.onload = function(){ctx1.drawImage(background1,0,0);}
to_draw_on.onload = function(){ctx2.drawImage(to_draw_on,0,0);}
/* code to draw on the second canvas */
This only results in the second canvas being beneath the first canvas, so that when I go to draw, I won't be able to trace the outline of the object.
Actually I am not sure why your version does not work (it should as-is!), but here's a version that uses your code and a bit of CSS to check the overlap. Read the comments in the CSS. When done, remove the extra code and enable .wrapper canvas { top: 0 } again.
Without the Javascript, I might add, I don't use Django.
However, it seems your JS new Image() has no size parameters and ctx.drawimage only has a location (0,0) but no (height,width) to work with.
So, height=0, width=0 yields nothing to overlap...
Forgot to mention: give both canvas a z-index so you can control which is on top.
UPDATE
Added Javascript and a third canvas to prove the code works as expected. Also inserted z-index per canvas as suggested before. Retrieving a few random pics from 'Lorem Picsum' to fill the canvas.
NOTICE that I use proper width/height parameters in my Javascript....
var canvas1 = document.getElementById("dorsal") , ctx1 = canvas1.getContext("2d");
var canvas2 = document.getElementById("dorsal-duplicate"), ctx2 = canvas2.getContext("2d");
var canvas3 = document.getElementById("extra-img") , ctx3 = canvas3.getContext("2d");
var background1 = new Image(512,256);
var to_draw_on = new Image(512,256);
var extra_img = new Image(512,256);
background1.src = "https://picsum.photos/512/512?random=0";
to_draw_on.src = "https://picsum.photos/512/512?random=1";
extra_img.src = "https://picsum.photos/512/512?random=2";
background1.onload = function(){ctx1.drawImage(background1,0,0);}
to_draw_on.onload = function(){ctx2.drawImage(to_draw_on,0,0);}
extra_img.onload = function(){ctx3.drawImage(extra_img,0,0);}
/* code to draw on the second canvas */
.wrapper {
position: relative;
width : 512px;
height: 512px;
}
.wrapper canvas {
position: absolute;
left: 0;
/* top : 0; /* temporary disabled */
/*ADDED*/
width: 100%; height: 100%; /* fill-parent */
border: 2px dotted black;
}
/*
To check the overlap:
- make #dorsal fill the top half of 512px
- make #dorsal-duplicate fill the bottom half of 512px
*/
#dorsal {
top : 0;
height: 50%;
background-color: green;
z-index: 1;
}
#dorsal-duplicate {
background-color: red;
bottom: 0;
height: 50%;
z-index: 2;
}
#extra-img {
background-color: blue;
left: 64px; bottom: 128px;
height: 50%; width: 75%;
z-index: 3;
}
<div class="wrapper">
<div class="pb-2 justify-content-center">
<h2>
<strong>Drawing test</strong>
</h2>
<p>removed width/height values from <canvas>, redundant.
<div class="justify-content-center">
<form enctype="multipart/form-data" method="post" action="">{% csrf_token %}
<div class="wrapper">
<canvas id="dorsal" ></canvas>
<canvas id="dorsal-duplicate"></canvas>
<canvas id="extra-img" ></canvas>
</div>
</form>
</div>
</div>
</div>
usage of static template tag is
{% static 'static_file_here.extension' %}
so basically the code background1.src = "{% static aspects.Dorsal.0 %}";
should be background1.src = "{% static 'aspects.Dorsal.0' %}";

save div as image on click

I have been looking for an answer on how to save a div as an image when I click save. I have looked everywhere but I cant seem to find an answer, I am using DIV and a preview button to convert the div into an image. The closest thing that i found to save as an image was http://jsfiddle.net/epistemex/kyjs655r/ this is close to what i need to save as an image, but the problem is that this is canvas and its not working with my code this is very similar to what I have my code is messy this is very similar https://jsfiddle.net/8ypxW/3/ I would like to integrate the save from the first URL to the second URL.
This is my script it is similar to the second URL
$(function() {
var element = $("#firstshirt"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
allowTaint: true,
logging: true,
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
});
var myform = document.getElementById('myform');
myform.onsubmit = function(e) { /* do some validation on event here */ };
$("#wrapper").hover(function() {
$("#boxes").css("border-color", "red");
},
function() {
$("#boxes").css("border-color", "transparent");
});
.container {
background-color: transparent;
width: 490px;
height: 500px;
border: 2px solid;
position: relative;
overflow: hidden;
/* Will stretch to specified width/height */
background-size: 490px 500px;
background-repeat: no-repeat;
}
.container5 {
background-color: transparent;
width: 220px;
height: 320px;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid red;
position: absolute;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input id="btn-Preview-Image" type="button" value="Preview"/>
<center>
<div id="firstshirt" class="container" style="float:left;">
<center><div id="wrapper"><div id="boxes" class="container5" style="float:center;">
<div data-bind="foreach:items" class="fix_backround">
<div class="item" data-bind="draggable:true,droppable:true">
<center>
<span id="texter" class="text" data-bind="text:$data"></span>
<input class="edit_text"/>
</center>
</div>
</div>
<a href="" download>
<span id="image" class="preview-area"></span>
</a>
</div>
</div>
</center>
<br><br><br><br>
</div>
</center>
<br/>
</center>
</div>
</div>
<center>
<div id="previewImage">
</div>
</center>
The above code is supposed to have an image but I didn't want to add it because that will need more code I want to keep it short and simple inside their is a text box and I want to save the whole div as an image on click just like the first URL
There is several same questions in SO. Saving Div Contents or Canvas as Image
How to take screenshot of a div with JavaScript?
One way of doing it is using canvas. Working solution is http://html2canvas.hertzen.com/
Here you can see some working examples of using this library
Use this library. ..
https://html2canvas.hertzen.com
Now just select the element and size.. it will take a snapshot as image..
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
},
width: 300,
height: 300
});

How can I stretch text on the canvas in with Fabric.js?

I want to stretch the font of a canvas Text object. How can I do this?
Example (before):
Example (after):
How could I implement this?
You can use scaleX to "squish" the text by scaling the text:
// "squish" the text to 60% of its original width
scaleX:0.60
Example code and a Demo
var canvas = new fabric.Canvas('canvas');
var myText = new fabric.Text('NEW TEXT',{
left: 50,
top: 60,
});
canvas.add(myText);
var mySquishedText = new fabric.Text('NEW TEXT',{
left: 50,
top: 100,
scaleX:0.60,
});
canvas.add(mySquishedText);
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="canvas" width=300 height=300></canvas>
[Update: #AndreaBogazzi adds that scaleX is better handled than the matrix ops]

Draw circle canvas and print canvas

I wanted to draw the circular canvas and wanted to download the canvas with same format. Following is css which i am using
canvas {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red;
}
At present i have just apply the css to canvas to look a like it will not print same in fabric js.
Is there any possible way? Because i am trying to create circular canvas and add text and wanted to print same canvas with text and styling.
Edit:
Is it possible to draw the circle with same styling in fabric.js
You cannot really have a circular canvas in fabricjs, but you can clip a canvas to look like a circle.
i did a circle that has radius half of the canvas, and is positioned in the center.
Effect is same as your example.
Look the fiddle:
var canvas = new fabric.Canvas('c');
canvas.clipTo = function(ctx) {
ctx.beginPath();
ctx.arc(200,200,200,0,2*Math.PI);
}
canvas.backgroundColor = 'blue';
var rect = new fabric.Rect({width: 100, height:100, fill:'red', top:30, left:30});
canvas.add(rect);
canvas.renderAll();
<script src="http://www.fabricjs.com/lib/fabric.js"></script>
<canvas id="c" width="400" height="400" ></canvas>

html 5 canvas not resizing after javascript resize

I have the following html and css for a Tetris game I am making:
html
<div id = "TetrisHolder">
<canvas id = "TetrisCanvas" style = "width:400px; height:500px"></canvas>
</div>
css
div#TetrisHolder {
display: table;
margin:auto;
background: black;
border: solid black 3px;
}
canvas#TetrisCanvas {
background: url(Resources/bg.png) no-repeat center;
background-size: cover ;
}
When I attempt to resize it with the following javascript, nothing happens. I have seen most other StackOverflow questions about resizing DOM elements answered this way, however it does not work for me. what am I missing?
note: I am aware that I will need to redraw what is on the canvas but all I want right now is to resize it.
js
function resize() {
canvas = document.getElementById("TetrisCanvas");
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth*0.6;
canvas.height = window.innerHeight*0.6;
}

Categories

Resources