I have a HTML page where an image is uploaded, the uploaded image is redrawn on a canvas element then converted to base64.
The first element works as expected but when I try to duplicate the code it doesn't work for the second code.
The code I have is:
<article>
<h3>Image 1</h3>
<p></p>
<li id="li_42" >
<div>
<input id="element_42" name="element_42" class="element file" type="file"/>
<br/>canvas:<br/>
<canvas id="canvas" width=64 height=64></canvas>
<textarea id="element_42_a" rows="5" ></textarea>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var maxW=64;
var maxH=64;
var input = document.getElementById('element_42');
var output = document.getElementById('element_42_a');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var img = new Image;
img.onload = function() {
var iw=img.width;
var ih=img.height;
var scale=Math.min((maxW/iw),(maxH/ih));
var iwScaled=iw*scale;
var ihScaled=ih*scale;
canvas.width=iwScaled;
canvas.height=ihScaled;
ctx.drawImage(img,0,0,iwScaled,ihScaled);
output.value = canvas.toDataURL("image/jpeg",0.5);
}
img.src = URL.createObjectURL(e.target.files[0]);
}
</script>
</div>
<article>
<h3>Image 2</h3>
<li id="li_43" >
<div>
<input id="element_43" name="element_43" class="element file2" type="file"/>
<br/>canvas:<br/>
<canvas id="canvas2" name="canvas2" width=64 height=64></canvas>
<textarea id="element_43_a" rows="5"></textarea>
<script>
var canvas=document.getElementById("canvas2");
var ctx=canvas2.getContext("2d");
var cw=canvas2.width;
var ch=canvas2.height;
var maxW=64;
var maxH=64;
var input = document.getElementsByClassName("element file2");(
var output = document.getElementById('element_43_a');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var img = new Image;
img.onload = function() {
var iw=img.width;
var ih=img.height;
var scale=Math.min((maxW/iw),(maxH/ih));
var iwScaled=iw*scale;
var ihScaled=ih*scale;
canvas2.width=iwScaled;
canvas2.height=ihScaled;
ctx.drawImage(img,0,0,iwScaled,ihScaled);
output.value = canvas2.toDataURL("image/jpeg",0.5);
}
img.src = URL.createObjectURL(e.target.files[0]);
}
</script>
</div>
</body>
</html>
Can someone please point me in the right direction and advise what I need to do, so both sections work?
getElementsByClassName returns an array and not a single element. If you want to use it, you would need to rewrite your second input to something like document.getElementsByClassName("element file2")[0]. (Note the [0] at the end.)
Try to keep your code DRY. You should not repeat so many lines and rely more on functions instead.
function redrawOnCanvas(myCanvas, myInput, myOutput) {
var canvas = document.getElementById(myCanvas);
var ctx = canvas.getContext("2d");
var maxW = 64;
var maxH = 64;
function handleFiles(e) {
var img = new Image;
img.onload = function() {
var iw = img.width;
var ih = img.height;
var scale = Math.min((maxW / iw), (maxH / ih));
var iwScaled = iw * scale;
var ihScaled = ih * scale;
canvas.width = iwScaled;
canvas.height = ihScaled;
ctx.drawImage(img, 0, 0, iwScaled, ihScaled);
output.value = canvas.toDataURL("image/jpeg", 0.5);
}
img.src = URL.createObjectURL(e.target.files[0]);
}
var input = document.getElementById(myInput);
var output = document.getElementById(myOutput);
input.addEventListener('change', handleFiles);
}
redrawOnCanvas('canvas', 'element_42', 'element_42_a');
redrawOnCanvas('canvas2', 'element_43', 'element_43_a');
<article>
<h3>Image 1</h3>
<li id="li_42">
<div>
<input id="element_42" name="element_42" class="element file" type="file" />
<br/>canvas:<br/>
<canvas id="canvas" width=64 height=64></canvas>
<textarea id="element_42_a" rows="5"></textarea>
</div>
</li>
</article>
<article>
<h3>Image 2</h3>
<li id="li_43">
<div>
<input id="element_43" name="element_43" class="element file2" type="file" />
<br/>canvas:<br/>
<canvas id="canvas2" name="canvas2" width=64 height=64></canvas>
<textarea id="element_43_a" rows="5"></textarea>
</div>
</li>
</article>
Related
I'm Currently Trying to apply a filter or filters to a Canvas Image after its been uploaded to the page and but if they want to change filters to more blurry or to another filter it removes the image and you will have to re-upload the image. I plan on making it where there is a button to several different filters and then they click on the filter they want to apply to the image. Any Ideas on How to fix it?
Right now when you go to upload the image, it will blur it to 5px but if you want it less or more blurry for example it will remove the image.
Thank You! In advance! Heres a Live Link of my code:
https://jsfiddle.net/mbyvvszy/
html:
<canvas id="canvas" width="1000" height="500" class="playable-canvas"></canvas>
<div id="image_div">
<h1> Choose an Image to Upload </h1>
<input type='file' name='img' id='uploadimage' />
</div>
<div class="playable-buttons">
<input id="edit" type="button" value="Edit" />
<input id="reset" type="button" value="Reset" />
</div>
<textarea id="code" class="playable-code">
ctx.filter = 'blur(5px)';
</textarea>
Javascript :
var drawnImage;
function drawImage(ev) {
console.log(ev);
var ctx = document.getElementById('canvas').getContext('2d'),
img = new Image(),
f = document.getElementById("uploadimage").files[0],
url = window.URL || window.webkitURL,
src = url.createObjectURL(f);
img.src = src;
img.onload = function() {
drawnImage = img;
ctx.drawImage(img, 0, 0);
url.revokeObjectURL(src);
}
}
document.getElementById("uploadimage").addEventListener("change", drawImage, false);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var textarea = document.getElementById('code');
var reset = document.getElementById('reset');
var edit = document.getElementById('edit');
var code = textarea.value;
function drawCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
eval(textarea.value);
}
reset.addEventListener('click', function() {
textarea.value = code;
drawCanvas();
});
edit.addEventListener('click', function() {
textarea.focus();
})
textarea.addEventListener('input', drawCanvas);
window.addEventListener('load', drawCanvas);
In drawCanvas, you clear the canvas but never re-draw the image. Just add a call to drawImage.
function drawCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
eval(textarea.value);
drawImage();
}
How do I display the selected image only?
So what I wanted to happen is that I have set of buttons where the customer do customize the image.
E.g. User choose shapes as circle then displays, then there's next step where user will choose patter then displays inside the circle.
For the Shapes, i have the idea that the transparent part is only inside (applies to circle,rectangle and heart)
here's my code:
function display(){
if (document.getElementById('shape1').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'http://image.flaticon.com/icons/png/512/33/33848.png';
}
if (document.getElementById('shape2').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'http://image.flaticon.com/icons/png/512/33/33848.png';
}
}
if (document.getElementById('pattern1').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTw_LgFWAcL6RzFH4EApgo69TX7xx6iUyPqLANgi5qdJ6QL9CY';
}
}
if (document.getElementById('pattern2').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'https://s-media-cache-ak0.pinimg.com/originals/8b/09/59/8b0959d17298294904713dbb94b00827.png';
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form role="form" id="showchoices" name="showchoices" method="post">
<div> <input type="radio" id="shape1" name="shape_design" value="CIRCLE" onchange="display()"/> O
<input type="radio" id="shape2" name="shape_design" value="RECTANGLE" onchange="display()"/> [] </div>
<div> <input type="radio" id="pattern1" name="pat_design" value="pattern2" onchange="display()"/> pattern1
<input type="radio" id="pattern2" name="pat_design" value="pattern1" onchange="display()"/> pattern2 </div> -- i would like the pattern not to overlap the shape, send to back and visible.
</form>
<div id="display_image" name="display_image" width="400px" height="400px"> </div>
The idea is something like this but without the animation .
Radio button do triggers to display the images, just static display.
-- http://jsfiddle.net/djnBD/
and I'm combining this process to this sample too - https://jsfiddle.net/Twisty/955j8so3/27/
THANK YOU IN ADVANCE!!!
Here is a short example of how you could make what you want with HTML and jQuery. Hope it helps.
$(document).ready(function(){
$(document).on("click", "*[data-toggle='add-img']", function() {
var newImgSrc = $(this).attr("data-img");
var newImgId = $(this).attr("data-img-id");
var newImg = "<img src='"+newImgSrc+"' id='"+newImgId+"' />";
appendToContainer(newImg, newImgId);
});
$(document).on("click","*[data-toggle='remove-img']", function() {
var newImgId = $(this).attr("data-img-id");
if ($("#"+newImgId).length>0) $("#"+newImgId).remove();
});
function appendToContainer(img, imgId) {
var imgContainer = $("#images-container");
var zIndex = imgContainer.children("img").last().css("z-index");
var newZIndex = parseInt(zIndex)+1;
if ($("#imgId").length===0) imgContainer.append(img);
$("#imgId").css({"z-index":newZIndex});
}
});
#images-container > img {
position: absolute;
top: 40;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div>
img 1
img 2
img 3
delete img 1
delete img 2
delete img 3
</div>
<div id="images-container"></div>
i tried using canvas, got it right now:
function display(){
if (document.getElementById('shape1').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'http://image.flaticon.com/icons/png/512/33/33848.png';
}
if (document.getElementById('shape2').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'http://image.flaticon.com/icons/png/512/33/33848.png';
}
}
if (document.getElementById('pattern1').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcTw_LgFWAcL6RzFH4EApgo69TX7xx6iUyPqLANgi5qdJ6QL9CY';
}
}
if (document.getElementById('pattern2').checked)
{
var ctx = document.getElementById('display_image').getContext('2d');
var imageObj = new Image();
imageObj.onload = function()
{ ctx.drawImage(imageObj, 0, 0); }
imageObj.src = 'https://s-media-cache-ak0.pinimg.com/originals/8b/09/59/8b0959d17298294904713dbb94b00827.png';
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form role="form" id="showchoices" name="showchoices" method="post">
<div> <input type="radio" id="shape1" name="shape_design" value="CIRCLE" onchange="display()"/> O
<input type="radio" id="shape2" name="shape_design" value="RECTANGLE" onchange="display()"/> [] </div>
<div> <input type="radio" id="pattern1" name="pat_design" value="pattern2" onchange="display()"/> pattern1
<input type="radio" id="pattern2" name="pat_design" value="pattern1" onchange="display()"/> pattern2 </div> -- i would like the pattern not to overlap the shape, send to back and visible.
</form>
<canvas id="display_image" name="display_image" width="400px" height="400px"> </canvas>
It might won't work here but its already fine in my codes.
I'm trying to add an image to an Canvas element. Canvas markup:
<?php foreach($fdsArray as $key => $value):?>
<div class="design" id="<?php echo $key;?>" data-design="<?php echo $value['url'];?>">
<canvas width="200" height="200"></canvas>
<p class="name"><?php echo $value['name'];?></p>
<p class="asset"><?php echo $value['asset'];?></p>
</div>
<?php endforeach;?>
Javascript:
<script type="text/javascript">
$(document).ready(function() {
$('.design').each(function() {
var design = $(this).attr('data-design');
var id = $(this).attr('id');
});
});
</script>
I want the image to show inside the canvas element. var design contains the url. Could anyone help me out?
Try
$(document).ready(function() {
$('.design').each(function() {
var design = $(this).attr('data-design');
var id = $(this).attr('id');
var canvas = $(this).find("canvas")[0];
var ctx = canvas.getContext("2d");
var img = new Image;
img.onload = function() {
ctx.drawImage(this, 0, 0);
};
img.src = design;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="design" id="image" data-design="http://lorempixel.com/technics/200/200/">
<canvas width="200" height="200"></canvas>
<p class="name">name</p>
<p class="asset">asset</p>
</div>
You will have to draw each image to its associated canvas through javascript using the canvas.drawImage method.
sample code follows:
var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");
var image = new Image();
image.src = "get image source from data- attribute";
image.onload = function() {
ctx.drawImage(image, 0, 0);
};
Use sth similar inside $.ready callback
...or in pure javascript:
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// a reference to #theURL
var theDiv = document.getElementById("theURL");
// the url from theDiv's data-design
var theURL = theDiv.getAttribute("data-design");
// new up an image
var img=new Image();
// when its fully loaded, call start()
img.onload=start;
// set the source of the new image to the url from data-design
img.src=theURL;
function start(){
// draw the new image to the canvas
ctx.drawImage(img,0,0);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<div class="design" id=theURL data-design="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png">
<canvas id="canvas" width=300 height=300></canvas>
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
I have created one app that allow to rotate image and crop image. When my first app start with original image, it is fine with crop image. But the problem is that when I rotate it once, my crop tools cannot get top,left,width,height of the image as the original one. My code as below .Can anyone help me with this problem?
My code:
<script>
$(document).ready(function($) {
$("#crop").click(function(e){
var Imgwidth = $('#face').width(),
Imgheight = $('#face').height(),
faceOffset = $('#face').offset(),
imgOffset = $('#imgHolder').find('img').offset(),
imgX1 = faceOffset.left-imgOffset.left,
imgY1 = faceOffset.top-imgOffset.top,
imgX2 =imgX1+Imgwidth,
imgY2 = imgY1+Imgheight;
var imgNval = new Array();
var imageSrc ='Penguins.jpg';
var imageObj=new Image();
imageObj.src=imageSrc;
selx1 = imgX1;
sely1 = imgY1;
selx2 = imgX2;
sely2 = imgY2;
selw = Imgwidth;
selh = Imgheight;
console.log(imgX1);
console.log(imgY1);
/*console.log(imgX2);
console.log(imgY2);*/
/*Passing from one page to another page*/
var canvas=document.getElementById("Mystore1");
var context=canvas.getContext("2d");
context.canvas.height = Imgheight;
context.canvas.width=Imgwidth;
context.drawImage(imageObj, imgX1, imgY1, selw, selh, 3, 3, Imgwidth, canvas.height-5);
});
});
</script>
<script type="text/javascript">
var loop=0;
$(document).ready(function(e) {
$("#left").click(function(){
loop+=90;
$("#imageHolder").rotate({ animateTo:loop });
});
});
$(document).ready(function(e) {
$("#right").click(function(){
loop-=90;
$("#imageHolder").rotate({animateTo:loop});
});
});
</script>
<script type="text/javascript">
$(function(){
$(".frame").draggable();
});
</script>
<canvas id="Mystore1">Your Browser Doesn't support HTML5 Canvas</canvas>
<div id="imgHolder">
<img src="Penguins.jpg" id="image"/>
</div>
<div class="frame"><img src="face.jpg" width="80" height="80" id="face" class="frames"/></div>
<button id="crop">Crop Me</button>
<button id="left">Left</button>
<button id="right">Right</button>
</body>
</html>