Image data transfer on drag and draw on canvas - javascript

I am uploading an image from PC. Then I read the file with file reader and display image by creating an img tag. Then I drag the image from the img tag into the canvas and draw it onto canvas. I'm using dragstart and onDrop events. I use datatransfer.setdata() and datatransfer.getdata() for the functionality. But on drop, the image drawn on canvas is not as original. It is a zoomed version. I don't know why is this happening!
Here is my code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Drag Demo</title>
<link href="copy.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<div style = "border:2px solid black;">
<canvas id = "canvas" style = "position:relative;width:1000px;height:1000px;top:0px;left:200px; border:2px solid black;" ondrop="dropIt(event);" ondragover="event.preventDefault();"> </canvas>
</div>
<div>
<input type="file" id="fileElem" accept="image/*" style="display:none" >
<div id="fileSelect" class="drop-area">Select some files</div>
</div>
<div id="thumbnail"></div>
</div>
<script type="text/javascript">
function dragIt(event) {
event.dataTransfer.setData("URL", event.target.id)
};
function dropIt(event) {
var theData = event.dataTransfer.getData("URL");
dt = document.getElementById(theData);
alert(dt.width);
alert(dt.height);
event.preventDefault();
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
ctx.drawImage(dt, 0, 0);
};
var count = 0;
var fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem");
fileElem.addEventListener("change",function(e){
var files = this.files
handleFiles(files)
},false)
fileSelect.addEventListener("click", function (e) {
fileElem.click();
e.preventDefault();
}, false);
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /image.*/;
if(!file.type.match(imageType)){
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
function handlefilereader(evt){
var target = evt.target || evt.srcElement;
image.src = evt.target.result;
}
if(document.all) {
image.src = document.getElementById('fileElem').value;
}
else {
var reader = new FileReader()
reader.onload = handlefilereader;
reader.readAsDataURL(file);
}
image.id = count;
count++;
thumbnail.appendChild(image);
alert(image.width);
image.draggable = true;
image.ondragstart = dragIt;
}
}
</script>
</body>
</html>

With canvas there are 2 'size' settings:
Through CSS you'll set the DISPLAY size, so to set the PHYSICAL size of the canvas, you MUST use its attributes. So NO CSS/Style.
Think about it this way: you create a IMAGE with physical size: (let's say) 400px*400px.
Then just as a normal image (jpg,png,gif) that has a physical size, you can still choose to change the DISPLAYED size and thus aspect-ratio: like 800px*600px. Even % is normally supported.
Hope this explains clearly WHY this happened and why your solution in your comment is also the correct solution!!

Related

How to add a dynamic id into a loader in canvas

I decided to load the images first then, draw it unto the canvas.
I want to add a button to allow the image to be moved around. For that I need the ID of the image. Does the image have an ID or can I give the image an id?
I want to be able to change the ID of the image with a loop. For example, everything in a certain area of the canvas becomes pit1marble1, pit1marble2.
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div>
<canvas id="myCanvas" width="1024" height="479" usemap="Canvas"></canvas>
<script>
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];
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var sources = {
background: 'MANCALA-game_bg_combined3.png',
};
loadImages(sources, function(images) {
context.drawImage(images.background, 0, 0, 1024, 479);
});
</script>
</body>
</html>

How to identify which canvas was clicked

In the code below there are two canvases clicking on which will open the file browser to open an image. I want to display the opened image in that canvas which was clicked. but
1) the problem is once the control is inside the handleFile I don't know which one of the canvases was originally clicked! how can I do that or how can I pass the canvas as parameter to the function handleFile ?
2)what if I wanted to write something onto textarea1 when clicked on canvas1, write to textarea2 when clicked on canvas2?
<html>
<head>
</head>
<body>
<input type="file" id="fileLoader" name="fileLoader" style="display: none" />
<canvas id="bufferCanvas"></canvas>
<canvas id="canvas1" width="200" height="200" style="cursor:pointer; border:2px solid #000000"></canvas>
<canvas id="canvas2" width="200" height="200" style="cursor:pointer; border:2px solid #ff6a00"></canvas>
<textarea id="textarea1" rows="4" cols="50"></textarea>
<textarea id="textarea2" rows="4" cols="50"></textarea>
<script src="upload.js"></script>
</body>
</html>
and here is upload.js
var fileLoader = document.getElementById('fileLoader');
var bufferCanvas = document.getElementById('bufferCanvas');
var allCanvases = document.getElementsByTagName("Canvas");
for (var i = 1; i < allCanvases.length; ++i) {
allCanvases[i].getContext("2d").fillStyle = "blue";
allCanvases[i].getContext("2d").font = "bold 20px Arial";
allCanvases[i].getContext("2d").fillText("image " + i + " of 1", 22, 20);
allCanvases[i].onclick = function (e) {
fileLoader.click(e);
}
}
fileLoader.addEventListener('change', handleFile, false);
var textarea1 = document.getElementById('textarea1');
var ctx = bufferCanvas.getContext('2d');
function handleFile(e) {
// I wanna know what canvas was clicked
//So I can display the image on the canvas which was clicked
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
bufferCanvas.width = img.width;
bufferCanvas.height = img.height;
ctx.drawImage(img, 0, 0);
dataURL = bufferCanvas.toDataURL('image/png'); // here is the most important part because if you dont replace you will get a DOM 18 exception;
// window.location.href = dataURL;// opens it in current windows for testing
textarea1.innerHTML = dataURL;
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
The problem is the onclick for the canvas is firing a click for the fileloader which has it's own event. To do what you want you can create global var to hold the <canvas> that was clicked.
var fileLoader = document.getElementById('fileLoader');
var bufferCanvas = document.getElementById('bufferCanvas');
var allCanvases = document.getElementsByTagName("Canvas");
var clickedCanvas = ''; //<---- will hold the triggering canvas
Then in your onclick function you can set html element to clickedCanvas
for (var i = 1; i < allCanvases.length; ++i) {
...
...
...
allCanvases[i].onclick = function (e) {
clickedCanvas = e.srcElement; // <--- set the clicked on canvas
fileLoader.click(e);
}
}
Now in function handleFile(e) you should be able to get the canvas from clickedCanvas
Also I would clear out clickedCanvas after you are done so you aren't retaining the last event.
Fiddle

Display image in canvas with Javascript?

I want to be able to click on a button on my page and load an image into a canvas at some X,Y coordinates?
The following code is what I have below. I would like the image to be in either image/photo.jpg or in the same directory but preferably in a subdirectory of the main page.
**Question: How to make a JPG show up in a canvas with the click of a button on the web page?
Code:
<!DOCTYPE html>
<html>
<script>
function draw(){
var ctx = document.getElementById("myCanvas").getContext("2d");
var img = new Image():
// img.src = "2c.jpg";
img.src = "/images/2c.jpg";
ctx.drawImage(img,0,0);
}
</script>
<body background="Black">
<div align="center">
<button type="button" onclick="draw()">Show Image on Canvas</button>
<canvas id="myCanvas" width="900" height="400" style="border:2px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="20px Arial";
ctx.fillText("Royal Flush $",500,50);
ctx.fillText("Striaght Flush $",500,80);
ctx.fillText("Flush $",500,110);
ctx.fillText("Four of a Kind $",500,140);
ctx.fillText("Full House $",500,170);
ctx.fillText("Three of a Kind $",500,200);
ctx.fillText("Two Pair $",500,230);
ctx.fillText("Pair of ACES $",500,260);
ctx.rect(495,10,270,350);
ctx.stroke();
</script>
</body>
</html>
March 6th, 2014 Code:
How is the following code not working. Do you have to have an ID tag on Canvas. The page will display but for some reason the image will not when the button is clicked. The image is in the same directory that my index.html file is in.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<style type="text/css">
canvas{
border: 5px solid black;
}
</style>
</html>
<button id="galaxy">Add image #1</button>
<button id="circles">Add image #2</button><span></span>
<canvas width="500" height="500"></canvas>
<script>
var Images = {};
function loadImages(list){
var total = 0;
document.querySelector("span").innerText = "...Loading...";
for(var i = 0; i < list.length; i++){
var img = new Image();
Images[list[i].name] = img;
img.onload = function(){
total++;
if(total == list.length){
document.querySelector("span").innerText = "...Loaded.";
}
};
img.src = list[i].url;
}
}
function drawImage(img){
var ctx = document.querySelector("canvas").getContext("2d");
ctx.drawImage(Images[img], 0, 0, 50, 50);
}
loadImages([{
name: "2c.jpg",
url: "mp.jpg"
},{
name: "mp.jpg",
url: "mp.jpg"
}]);
document.querySelector("#galaxy").addEventListener("click", function(){
drawImage("galaxy");
});
document.querySelector("#circles").addEventListener("click", function(){
drawImage("weirdCircles");
});
</script>
</html>
Wait till the image is loaded before drawing:
var img = new Image();
img.onload = function(){ /*or*/ img.addEventListener("load", function(){
ctx.drawImage(img,0,0); ctx.drawImage(img,0,0);
}; };
img.src = "/images/2c.jpg";
Demo: http://jsfiddle.net/DerekL/YcLgw/
If you have more than one image in your game,
It is better to preload all images before it starts.
Preload images: http://jsfiddle.net/DerekL/uCQAH/ (Without jQuery: http://jsfiddle.net/DerekL/Lr9Gb/)
If you are more familiar with OOP: http://jsfiddle.net/DerekL/2F2gu/
function ImageCollection(list, callback){
var total = 0, images = {}; //private :)
for(var i = 0; i < list.length; i++){
var img = new Image();
images[list[i].name] = img;
img.onload = function(){
total++;
if(total == list.length){
callback && callback();
}
};
img.src = list[i].url;
}
this.get = function(name){
return images[name] || (function(){throw "Not exist"})();
};
}
//Create an ImageCollection to load and store my images
var images = new ImageCollection([{
name: "MyImage", url: "//example.com/example.jpg"
}]);
//To pick and draw an image from the collection:
var ctx = document.querySelector("canvas").getContext("2d");
ctx.drawImage(images.get("MyImage"), 0, 0);

Save canvas in client side

JavaScript
if (!window.Clipboard) {
var pasteCatcher = document.createElement("apDiv1");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.opacity = 0;
document.body.appendChild(pasteCatcher);
pasteCatcher.focus();
document.addEventListener("click", function() { pasteCatcher.focus(); });
}
window.addEventListener("paste", onPasteHandler);
function onPasteHandler(e)
{
if(e.clipboardData) {
var items = e.clipboardData.items;
if(!items){
alert("Image Not found");
}
for (var i = 0; i < items.length; ++i) {
if (items[i].kind === 'file' && items[i].type === 'image/png') {
var blob = items[i].getAsFile(),
source = window.webkitURL.createObjectURL(blob);
pastedImage = new Image();
pastedImage.src = source;
pasteData();
}
}
}
}
function pasteData()
{
drawCanvas = document.getElementById('drawCanvas1');
ctx = drawCanvas.getContext( '2d' );
ctx.clearRect(0, 0, 640,480);
ctx.drawImage(pastedImage, 0, 0);
}
DIV
<div id="apDiv1" contenteditable='true'>Paste Test</div>
Above javascript will capture image from clipboard and paste in the DIV. How do I save the canvas in clientside. I'm not using any server so i need to save the canvas in client side.
I found that canvas.toDataURL() will convert contents as a base64 encoded PNG file, but how do I do if i want the image save in my local. Let say, I have a folder Image in my C://. How do I do if i want the image saved in particular folder.
Just set an html img element's src to canvas.toDataURL()
Then right-click-save-as.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.fillRect(50,50,150,75);
var theImage=document.getElementById("toImage");
theImage.src=canvas.toDataURL();
Here's a complete example:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.fillRect(50,50,150,75);
var theImage=document.getElementById("toImage");
theImage.src=canvas.toDataURL();
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
<img id="toImage" width=300 height=300>
</body>
</html>

uploading an image and display in browser window

I have implemented a code in which image is uploaded into the browser and shown as thumbnail. Then it can also be dragged into a canvas area. But when i run it in chrome, it is not opening the window to upload the file. First the image is uploaded, then its thumbnail is created. But it is not working in chrome.
Here is my code,
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Drag Demo</title>
<link href="copy.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<div style = "border:2px solid black;">
<canvas id = "canvas" style = "position:relative;width:300px;height:300px;top:0px;left:500px; border:2px solid black;" ondrop="dropIt(event);" ondragover="event.preventDefault();"> </canvas>
</div>
<div>
<input type="file" id="fileElem" accept="image/*" style="display:none" >
<div id="fileSelect" class="drop-area">Select some files</div>
</div>
<div id="thumbnail"></div>
</div>
<script type="text/javascript">
function dragIt(event) {
event.dataTransfer.setData("Text", event.target.id)
};
function dropIt(event) {
var theData = event.dataTransfer.getData("Text");
dt = document.getElementById(theData);
event.preventDefault();
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
ctx.drawImage(dt, 100, 0,dt.width,dt.height);
};
var count = 0;
var fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem");
fileElem.addEventListener("click",function(e){
var files = this.files
handleFiles(files)
},false)
fileSelect.addEventListener("click", function (e) {
fileElem.click();
e.preventDefault();
}, false);
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /image.*/;
if(!file.type.match(imageType)){
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
thumbnail.appendChild(image)
var reader = new FileReader()
reader.onload = (function(aImg){
return function(e){
aImg.src = e.target.result;
};
}(image))
image.id = count;
count++;
image.draggable = true;
image.ondragstart = dragIt;
var ret = reader.readAsDataURL(file);
}
}
</script>
</body>
</html>
Just run the code on a server and it will work!

Categories