Drag images over canvas and save png - javascript

I'm creating an application with the image of a christmas tree that is placed in a canvas element , where there is the possibility of drag images over it . After the tree is decorated with the draggable images, the user has to be able to save the entire composition (canvas + images) as a PNG file . The problem is: when I drag the images to the canvas, they are hidden behind the christmas tree. Can you please help me to fix it?
Here's the code:
<html>
<head>
<script>
function allowDrop(e)
{
e.preventDefault();
}
function drag(e)
{
//store the position of the mouse relativly to the image position
e.dataTransfer.setData("mouse_position_x",e.clientX - e.target.offsetLeft );
e.dataTransfer.setData("mouse_position_y",e.clientY - e.target.offsetTop );
e.dataTransfer.setData("image_id",e.target.id);
}
function drop(e)
{
e.preventDefault();
var image = document.getElementById( e.dataTransfer.getData("image_id") );
var mouse_position_x = e.dataTransfer.getData("mouse_position_x");
var mouse_position_y = e.dataTransfer.getData("mouse_position_y");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var imageObj=new Image();
imageObj.onload=function(){
ctx.save();
ctx.drawImage(this,0,0,canvas.width,canvas.height);
ctx.restore();
}
imageObj.src="bg.png";
// the image is drawn on the canvas at the position of the mouse when we lifted the mouse button
ctx.drawImage( image , e.clientX - canvas.offsetLeft - mouse_position_x , e.clientY - canvas.offsetTop - mouse_position_y );
}
function convertCanvasToImage() {
var canvas = document.getElementById('canvas');
var image_src = canvas.toDataURL("image/png");
window.open(image_src);
}
</script>
<style type="text/css">
body {
text-align: center;
}
#wrapper {
text-align: left;
width: 870px;
height:566px;
margin-left: auto;
margin-right: auto;
}
#options{
width: 70px;
height:566px;
float:left;
}
#options img {
margin-bottom: 15px;
}
#canvas{
width:800px;
height:566px;
float:left;
background-image:url(../images/bg.png);
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div id="options">
<img id="img1" draggable="true" ondragstart="drag(event)" src='estrela.png'>
<img id="img2" draggable="true" ondragstart="drag(event)" src='bola.png'>
<img id="img3" draggable="true" ondragstart="drag(event)" src='sino.png'>
<img id="img4" draggable="true" ondragstart="drag(event)" src='bota.png'>
<img id="img5" draggable="true" ondragstart="drag(event)" src='anjo.png'>
<img id="img6" draggable="true" ondragstart="drag(event)" src='laco.png'>
</div>
<canvas id="canvas" onDrop="drop(event)" onDragOver="allowDrop(event)" width="800" height="566"></canvas>
<input type="button" onClick="convertCanvasToImage()" value="Gerar Imagem" style="float:right"/>
</body>
Thanks!

Check out this post which allows you to drag images from a toolbar and drop them on the canvas:
HTML5 drag and drop images from a toolbar to a canvas
When you're done creating your tree, you can save the canvas as an image by converting it to an image and displaying the image in a new browser tab. The user can then right-click-save that image to their local drive:
$("#save").click(function(){
var html="<p>Right-click on image below and Save-Picture-As</p>";
html+="<img src='"+canvas.toDataURL()+"' alt='image from canvas'/>";
var tab=window.open();
tab.document.write(html);
});
Some browsers (Chrome, Firefox) even allow the user to right-click the canvas element itself and save it as an image.

Related

How to get event property again for already dragged image

I have image that I want to drag and drop infinitely.From first box to second box when I move,image disappear from first box.Not to lose image created same image on first box again using .appendchild(img) method.I want to drag image from initial position,not from where I dropped.So I changed draggable property as false when I dropped image into box.It creates image on first box,there's no problem.But I can't drag and drop it from first box to third again because that image has no event properties.I want to give them those properties again and it should be repeated because I want to do it forever.
Here's what I tried
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2,#div3 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
var img = document.createElement("img");
img.src = "https://mikasasports.com/wp-content/uploads/2015/04/MVA2001.png";
var src = document.getElementById("div1");
img.style.width="88px";
img.style.height="31px";
src.appendChild(img);
drag1.draggable=false;
}
</script>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the three div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="https://mikasasports.com/wp-content/uploads/2015/04/MVA2001.png" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>

Drag and Drop ( Copy ) in another Div is lining up

I'm doing a Drag and Drop project where when dropping an image in another Div, it has to stay in the same place where I left it.
The problem is the img are lining up the left.
HTML CODE :
<html>
<head>
<link type="text/css" rel="stylesheet" media="screen" href="css/testednd.css" /> <!-- CSS das div's -->
<script src="js/testednd.js"></script> <!-- Script clickImagem -->
</head>
<body>
<div id="conteudo-left" style="position:static; left:10px; top:20px; width:300; height:660; z-index:-1; overflow: auto">
<form name="form_dnd_left" border = 1>
<ul>
<li><img id="drag1" src="images/Comp3.jpg" draggable="true" ondragstart="drag(event)" alt="" /></li>
</ul>
</form>
</div>
<div class="conteudo" id="conteudo" ondrop="drop(event)" ondragover="allowDrop(event)"><!-- abrimos a div conteudo do meio-->
</div>
</body>
</html>
CSS CODE
#conteudo-left{
width:300px;
height:660px;
float:left;
background-color:#FFF;
}
#conteudo{
width:600px;
height:460px;
float:left;
background-color:#ff1;
display: initial;
margin: auto;
.columns {
}
}
JavaScript Code
///Drag'n Drop functions
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.effectAllowed = "copy";
}
function drop(ev)
{
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var copyimg = document.createElement("img");
var original = document.getElementById(data);
copyimg.src = original.src;
ev.target.appendChild(copyimg);
}
Can somebody help me??
Thanks for all !!
Update:
From the event you can get the position of the drag and minus the offset of the parent, thus we can drop it in that exact location.
function drop(ev)
{
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var copyimg = document.createElement("img");
var parent = document.createElement("conteudo");
var original = document.getElementById(data);
copyimg.src = original.src;
copyimg.style.position = "absolute";
copyimg.style.left = ev.clientX - ev.target.offsetLeft+"px";
copyimg.style.top = ev.clientY - ev.target.offsetTop+"px";
ev.target.appendChild(copyimg);
}
Old Answer:
Do you want something like this?
CSS used to make this is:
padding-left: 150px;
padding-top: 125px;
box-sizing: border-box;
So I gave half of the width and height as padding so that the images get positioned there! also I am using box-sizing:border-box so that the padding does not get added to the dimensions of the div.
Note: I have reduced the dimesions of the boxes so that they fit perfectly inside the demo window, please set the padding-top andpadding-left` to about half of the width of the respective dimensions!
///Drag'n Drop functions
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.effectAllowed = "copy";
}
function drop(ev)
{
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var copyimg = document.createElement("img");
var parent = document.createElement("conteudo");
var original = document.getElementById(data);
copyimg.src = original.src;
copyimg.style.position = "absolute";
copyimg.style.left = ev.clientX - ev.target.offsetLeft+"px";
copyimg.style.top = ev.clientY - ev.target.offsetTop+"px";
ev.target.appendChild(copyimg);
}
#conteudo-left{
width:150px;
height:330px;
float:left;
background-color:#FFF;
}
#conteudo{
width:300px;
height:250px;
position:relative;
float:left;
background-color:#ff1;
display: initial;
margin: auto;
}
<html>
<head>
<link type="text/css" rel="stylesheet" media="screen" href="css/testednd.css" /> <!-- CSS das div's -->
<script src="js/testednd.js"></script> <!-- Script clickImagem -->
</head>
<body>
<div id="conteudo-left" style="position:static; left:10px; top:20px; width:300; height:660; z-index:-1; overflow: auto">
<form name="form_dnd_left" border = 1>
<ul>
<li><img id="drag1" src="http://via.placeholder.com/50x50" draggable="true" ondragstart="drag(event)" alt="asdfasdf" /></li>
</ul>
</form>
</div>
<div class="conteudo" id="conteudo" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>
</body>
</html>
On the drop event you get the x and y coords of the mouse and set the style to be absolute in that position. Note that the top left corner of the image will snap to the exact coord of the mouse pointer. See below:
///Drag'n Drop functions
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.effectAllowed = "copy";
}
function drop(ev)
{
ev.preventDefault();
var x = ev.clientX;
var y = ev.clientY;
var data = ev.dataTransfer.getData("text");
var copyimg = document.createElement("img");
var original = document.getElementById(data);
copyimg.src = original.src;
ev.target.appendChild(copyimg);
copyimg.setAttribute("style", "position: absolute; top: "+y+"px; left:"+x+"px;");
}
#conteudo-left{
width:150px;
height:330px;
float:left;
background-color:#FFF;
}
#conteudo{
width:300px;
height:250px;
float:left;
background-color:#ff1;
display: initial;
margin: auto;
box-sizing: border-box;
}
<html>
<head>
<link type="text/css" rel="stylesheet" media="screen" href="css/testednd.css" /> <!-- CSS das div's -->
<script src="js/testednd.js"></script> <!-- Script clickImagem -->
</head>
<body>
<div id="conteudo-left" style="position:static; left:10px; top:20px; width:300; height:660; z-index:-1; overflow: auto">
<form name="form_dnd_left" border = 1>
<ul>
<li><img id="drag1" src="http://via.placeholder.com/50x50" draggable="true" ondragstart="drag(event)" alt="asdfasdf" /></li>
</ul>
</form>
</div>
<div class="conteudo" id="conteudo" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>
</body>
</html>

How to make html div with text over image downloadable/savable for users?

I have a div that takes a user image and places user text over it. My goal is for the users to, after seeing the preview and customizing the image/text to their like, be able to download or save the image with the click of a button. Is this possible? Here's my code: (I'm new to html/css so please forgive ugly formatting/methods)
HTML:
<script `src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>`
<p>DOM-rendered</p>
<p> </p>
<div id="imagewrap" class="wrap" style="border-style: solid;">
<img src="../images/environment.gif" id="img_prev" width="640" height="640" />
<h3 class="desc">Something Inspirational</h3>
</div>
<div id="canvasWrapper" class="outer">
<p>Canvas-rendered (try right-click, save image as!)</p>
<p>Or, <a id="downloadLink" download="cat.png">Click Here to Download!</a>
</div>
CSS:
.desc {
text-align: center;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
background-color: white;
}
JavaScript:
window.onload = function() {
html2canvas(document.getElementById("imagewrap"), {
onrendered: function(canvas) {
canvas.className = "html2canvas";
document.getElementById("canvasWrapper").appendChild(canvas);
var image = canvas.toDataURL("image/png");
document.getElementById("downloadLink").href = image;
},
useCORS: true
});
}
function changePicture(image) {
var at = $(image).attr('at');
var newpath = '../images/' + at;
$("#img_prev").attr('src', newpath);
}
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img_prev')
.attr('src', e.target.result)
.width(640)
.height(640);
};
reader.readAsDataURL(input.files[0]);
}
};
$(document).on("click", '.font-names li a', function() {
$("#imagewrap h3").css("font-family", $(this).parent().css("font-family"));
$("#new_tile_font_style").val($(this).parent().css("font-family"));
});
$(document).on("click", '.font-sizes li a', function() {
$("#imagewrap h3").css("font-size", $(this).parent().css("font-size"));
$("#new_tile_font_size").val($(this).parent().css("font-size") + "px");
});
$(document).on("click", '.font-colors li a', function() {
$("#imagewrap h3").css("color", $(this).parent().css("color"));
$("#new_tile_font_color").val($(this).parent().css("color"));
});
$("#new_tile_quote").on('keyup', function() {
var enteredText = $("#new_tile_quote").val().replace(/\n/g, "<br>");
$("#imagewrap h3").html(enteredText);
});
What you're trying to accomplish is entirely possible using just HTML, JS, and CSS, with no server-side code. Here is a simplified demo that uses the html2canvas library to render your entire DOM element to a canvas, where the user can then download it.
Be sure to click "Full page" on the demo so you can see the whole thing!
window.onload = function() {
html2canvas(document.getElementById("imagewrap"), {
onrendered: function(canvas) {
canvas.className = "html2canvas";
document.getElementById("canvasWrapper").appendChild(canvas);
var image = canvas.toDataURL("image/png");
document.getElementById("downloadLink").href = image;
},
useCORS: true
});
}
.desc {
text-align: center;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
background-color: white;
}
#wow {
color: red;
display: block;
transform: translate(0px, -12px) rotate(-10deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div class="outer">
<p>DOM-rendered</p>
<p> </p>
<div id="imagewrap" class="wrap" style="border-style: solid;">
<img src="https://i.imgur.com/EFM76Qe.jpg?1" id="img_prev" width="170" />
<h3 class="desc">Something <br /><span style="color: blue;">Inspirational</span></h3>
<span id="wow">WOW!</span>
</div>
</div>
<div id="canvasWrapper" class="outer">
<p>Canvas-rendered (try right-click, save image as!)</p>
<p>Or, <a id="downloadLink" download="cat.png">Click Here to Download!</a>
</div>
Here's a quick demo that shows how to use JavaScript to convert your markup into a canvas, then render that into an image and replace it on the page.
document.getElementById('generate').onclick = generateImage;
function generateImage() {
var container = document.getElementById('image_text');
var imgPrev = document.getElementById('img_prev');
var desc = document.getElementById('desc');
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.setAttribute('width', container.clientWidth);
canvas.setAttribute('height', container.clientHeight);
context.drawImage(imgPrev, 0, 0);
context.font = "bold 20px serif";
context.fillText(desc.innerHTML, 0, container.clientHeight-20);
context.strokeRect(0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL();
var imgFinal = new Image();
imgFinal.src = dataURL;
container.parentNode.insertBefore(imgFinal, container.nextSibling);
container.remove();
document.getElementById('generate').remove();
}
#image_text {
display: inline-block;
border: 1px solid #000;
}
<div id="image_text">
<div class="wrap">
<img src= "https://placekitten.com/g/200/300" id="img_prev" crossorigin="anonymous" />
<h3 id="desc" contenteditable>Something Inspirational</h3>
</div>
</div>
<button id="generate">Generate Image</button>
You can replace the image file with anything you like. I've added a crossorigin property to the img tag, and this is because canvases that use resources from other sites cannot be exported unless a crossorigin attribute is specified (if your scripts and images are on the same domain, this is unnecessary).
I've also made the h3 tag editable. You can click on the text and start typing to change what it says, then click "generate image" and save the rendered output.
This script is just a demonstration. It is not bulletproof, it is only a proof-of-concept that should help you understand the techniques being used and apply those techniques yourself.
The javascript creates a canvas element (detached from the DOM), and sizes it according to the container div in your markup. Then it inserts the image into the canvas (it inserts it at the top-left corner), loads the text from your h3 tag and puts it near the bottom-left of the canvas, and converts that canvas to a data-uri. Then it creates a new img element after the container and deletes the container and button.

swapping child elements of div using javascript by drag and drop

I tried swapping two elements inside div1 and div2 tag but only the first replace function executes properly the other element is not swapped
either one of the div is getting swapped at once but when i try to swap both at same time it doesn't happen please help me out
*
<head>
<style type="text/css">
#div1 {
width:350px;
height:70px;
padding:10px;
border:1px solid #aaaaaa;
}
#div2 {
width:350px;
height:70px;
padding:10px;
border:1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
var child = ev.target;
var parents = child.parentNode;
ev.dataTransfer.setData("child1", child.id);
ev.dataTransfer.setData("parent1", parents.id);
}
function drop(ev) {
ev.preventDefault();
var childid1 = ev.dataTransfer.getData("child1");
var parentid1 = ev.dataTransfer.getData("parent1");
var parent1 = document.getElementById(parentid1);
var c = ev.currentTarget.childNodes;
var childid2 = c[1].id;
parent1.replaceChild(c[1], document.getElementById(childid1));
var parent2 = ev.currentTarget;
parent2.removeChild(c[1]);
parent2.appendChild(document.getElementById(childid1));
}
</script>
</head>
<body>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">
</div>
<br>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<img id="drag2" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="236" height="49">
</div>
</body>
I think your fundamental flaw is that you do not cater for the fact that when you do your first replaceChild, the image you are inserting is removed from its parent so it is no longer there to replace with the second image.
I found your variable names somewhat confusing, and have rewritten your code in a simpler fashion as follows:
function allowDrop (ev) {
ev.preventDefault ();
}
function drag (ev) {
ev.dataTransfer.setData ("src", ev.target.id);
}
function drop (ev) {
ev.preventDefault ();
var src = document.getElementById (ev.dataTransfer.getData ("src"));
var srcParent = src.parentNode;
var tgt = ev.currentTarget.firstElementChild;
ev.currentTarget.replaceChild (src, tgt);
srcParent.appendChild (tgt);
}
You can test this code at jsFiddle

How to store result of drag and drop as a image

I want to take the screenshot of the result of drag and drop, but I don't know how to do.
Actually, I found 2 javascript and using HTML5 such as html2canvas and canvas2image.
I am now combining them together, but it's still meet some problem with the canvas2image.
Please help me solve this problem if you have same experience, thank you a lot.
Please help me, I've been stock here for days.
Drag and drop code.
<script>
$(function() {
$( "#draggable" ).draggable();
$( "#draggable2" ).draggable();
$( "#droppable" ).droppable({
hoverClass: "ui-state-active",
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
</script>
Image generation code
<script>
window.onload = function() {
function convertCanvas(strType) {
if (strType == "JPEG")
var oImg = Canvas2Image.saveAsJPEG(oCanvas, true);
if (!oImg) {
alert("Sorry, this browser is not capable of saving " + strType + " files!");
return false;
}
oImg.id = "canvasimage";
oImg.style.border = oCanvas.style.border;
oCanvas.parentNode.replaceChild(oImg, oCanvas);
}
function convertHtml(strType) {
$('body').html2canvas();
var queue = html2canvas.Parse();
var canvas = html2canvas.Renderer(queue,{elements:{length:1}});
var img = canvas.toDataURL();
convertCanvas(strType);
window.open(img);
}
document.getElementById("html2canvasbtn").onclick = function() {
convertHtml("JPEG");
}
}
</script>
HTML code
<body>
<h3>Picture:</h3>
<div id="draggable">
<img src='http://1.gravatar.com/avatar/1ea64135b09e00ab80fa7596fafbd340? s=50&d=identicon&r=R'>
</div>
<div id="draggable2">
<img src='http://0.gravatar.com/avatar/2647a7d4b4a7052d66d524701432273b?s=50&d=identicon&r=G'>
</div>
<div id="dCanvas">
<canvas id="droppable" width="500" height="500" style="border: 2px solid gray" class="ui-widget-header" />
</div>
<input type="button" id="bGenImage" value="Generate Image" />
<div id="dOutput"></div>
</body>
A working example, without libraries:
<html>
<head>
<script>
function allowDrop(e)
{
e.preventDefault();
}
function drag(e)
{
//store the position of the mouse relativly to the image position
e.dataTransfer.setData("mouse_position_x",e.clientX - e.target.offsetLeft );
e.dataTransfer.setData("mouse_position_y",e.clientY - e.target.offsetTop );
e.dataTransfer.setData("image_id",e.target.id);
}
function drop(e)
{
e.preventDefault();
var image = document.getElementById( e.dataTransfer.getData("image_id") );
var mouse_position_x = e.dataTransfer.getData("mouse_position_x");
var mouse_position_y = e.dataTransfer.getData("mouse_position_y");
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// the image is drawn on the canvas at the position of the mouse when we lifted the mouse button
ctx.drawImage( image , e.clientX - canvas.offsetLeft - mouse_position_x , e.clientY - canvas.offsetTop - mouse_position_y );
}
function convertCanvasToImage() {
var canvas = document.getElementById('canvas');
var image_src = canvas.toDataURL("image/png");
window.open(image_src);
}
</script>
</head>
<body>
<div style="float:left" >
<div>
<img id="img1" draggable="true" ondragstart="drag(event)" src='img1.png'>
<img id="img2" draggable="true" ondragstart="drag(event)" src='img2.png'>
<input type="button" onclick="convertCanvasToImage()" value="Generate Image" style="float:right"/>
</div>
<canvas id="canvas" ondrop="drop(event)" ondragover="allowDrop(event)" width="500" height="500" style="border: 1px solid gray" />
</div>
</body>
The images must have the same origin in order to use toDataURL.
The resulting image is open on a new window, as in your code, but you can also, append it on the page, save on the disk or upload it on a server.
http://fiddle.jshell.net/gael/GF96n/4/

Categories