So i am getting to know Canvas element and i made simple Canvas based gallery to get me started.
I use setInterval to update src of my Image and than onLoad to draw it in canvas. Problem is that it works in Chrome but not in Safari or IE.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var img = new Image();
img.src = "http://lorempixel.com/g/400/400";
img.onload = function() {
console.log('new image time');
context.drawImage(img, 0, 0);
};
setInterval(function(){
img.src = "http://lorempixel.com/g/400/400";
}, 4000);`
I made a fiddle: http://jsfiddle.net/lukaMis/T92TW/3/
So why doesn't setInterval run in Safari?
So
I found out it was catching of the browser problem. Browser catche request for img.src and it did not work. If if append timestamp to request it works:
_time = Date.now();
img.src = "http://lorempixel.com/g/400/400" + "?" + _time;
fiddle: http://jsfiddle.net/T92TW/5
Luka
Related
I want to save an image of the canvas tag, but when i try create an image from the canvas it tells me "SecurityError: The operation is insecure", which i believe is problems with the canvas coming from another domain than what im on. This canvas is a map which is generated with openlayers3.
var canvas = document.getElementsByClassName('ol-unselectable')[0];
var dataURL = canvas.toDataURL('image/png');
var window = window.open();
window.document.write('<img src='+dataURL+'/>');
I've also tried
canvas.toBlob(function(blob) {
saveAs(blob, 'map.png')
}
Is there an easy work around so the canvas is not tainted?
You tried write in new browser window from another window this is impossible without https protocol or localhost. But you can create new img in currently window.
var canvas = document.getElementsByClassName('ol-unselectable')[0];
var dataURL = canvas.toDataURL('image/png');
var img = new Image();
img.width = 1000;
img.height = 1000;
img.src = dataURL;
img.onload = function () {
document.body.append(img);
}
I wrote a few lines of code to draw an image but seems like it keeps on loading, I tried some W3 School code using the basic implementation but that works fine.
What is happening here is it looks like its stuck in some invisible loop and unable to draw an image.
<script>
var canvas=null;
var context=null;
setup=function(){
canvas=document.getElementById("my_canvas");
context=canvas.getContext('2d');
canvas.width=1200;
canvas.height=720;
img=new Image();
img.onload=onImageLoad;
img.src="http://imgge.bg.ac.rs/images/logo1.jpg";
context.drawImage(img,192,192);
};
onImageLoad=function(){
document.write("done !!");
context.drawImage(img,155,10);
};
setup();
</script>
I replaced your document.write() with a console.log() and it works fine:
var canvas = null;
var context = null;
var setup = function() {
canvas = document.getElementById("my_canvas");
context = canvas.getContext('2d');
canvas.width = 1200;
canvas.height = 720;
img = new Image();
img.onload = onImageLoad;
img.src = "http://imgge.bg.ac.rs/images/logo1.jpg";
context.drawImage(img, 192, 192);
};
onImageLoad = function() {
console.log("done !!");
context.drawImage(img, 155, 10);
};
setup();
<canvas id="my_canvas"></canvas>
For the reason why document.write() causes the canvas to not be displayed, read document.write() overwriting the document?
You might notice a difference between the first and consecutive runs due to img being cached by your browser. A cached image is immediately available for drawing within the setup() function.
First you don't need to write context.drawImage(img,192,192); two times only write inside the image.onload() function. when you write anything using using document.write("Done !"); , it will write the content on this document(HTML) page and may create problems. Instead of that write message on <p> tag instead of on whole document.
here is a snippet for your code:
var canvas=null;
var context=null;
setup=function(){
canvas=document.getElementById("my_canvas");
context=canvas.getContext('2d');
canvas.width=1200;
canvas.height=720;
img=new Image();
img.onload=onImageLoad;
img.src="http://imgge.bg.ac.rs/images/logo1.jpg";
//context.drawImage(img,192,192);
};
onImageLoad=function(){
context.drawImage(img,155,10);
document.getElementById("report").innerHTML="Done !";
};
setup();
<canvas id="my_canvas"></canvas>
<p id="report"></p>
I am working with a single canvas that allows the user to click on a window pane in a window image. The idea is to show where the user has clicked. The image will then be modified (by drawing a grill on the window) and then saved to in JPEG. I am saving the canvas image prior to the click function because I don't want the selection box to show in the final image. However, Firefox often displays a blank canvas when restoring the canvas where IE and Chrome do not. This works perfectly in Chrome and IE. Any suggestions? Does Firefox have a problem with toDataURL()? Maybe some async issue going on here? I am also aware that saving a canvas in this fashion is memory intensive and there may be a better way to do this but I'm working with what I have.
Code:
/**
* Restores canvas from drawingView.canvasRestorePoint if there are any restores saved
*/
restoreCanvas:function()
{
var inverseScale = (1/drawingView.scaleFactor);
var canvas = document.getElementById("drawPop.canvasOne");
var c = canvas.getContext("2d");
if (drawingView.canvasRestorePoint[0]!=null)
{
c.clearRect(0,0,canvas.width,canvas.height);
var img = new Image();
img.src = drawingView.canvasRestorePoint.pop();
c.scale(inverseScale,inverseScale);
c.drawImage(img, 0, 0);
c.scale(drawingView.scaleFactor, drawingView.scaleFactor);
}
},
/**
* Pushes canvas into drawingView.canvasRestorePoint
*/
saveCanvas:function()
{
var canvas = document.getElementById("drawPop.canvasOne");
var urlData = canvas.toDataURL();
drawingView.canvasRestorePoint.push(urlData);
},
EXAMPLE OF USE:
readGrillInputs:function()
{
var glassNum = ir.get("drawPop.grillGlassNum").value;
var panelNum = ir.get("drawPop.grillPanelNum").value;
drawingView.restoreCanvas();
drawEngine.drawGrill(glassNum, panelNum,null);
drawingView.saveCanvas();
},
sortClick:function(event)
{
..... //Sorts where user has clicked and generates panel/glass num
.....
drawingView.showClick(panelNum, glassNum);
},
showClick:function(panelNum, glassNum)
{
var glass = item.panels[panelNum].glasses[glassNum];
var c = drawEngine.context;
drawingView.restoreCanvas();
drawingView.saveCanvas();
c.strokeStyle = "red";
c.strokeRect(glass.x, glass.y, glass.w, glass.h);
},
By just looking at the code setting the img.src is an async action to retrieve the image, so when you try to draw it 2 lines later to the canvas, it probably hasn't been loaded yet (having it in cache will make it return fast enough that it might work).
You should instead use an img.onload function to draw the image when it has loaded.
restoreCanvas:function()
{
var inverseScale = (1/drawingView.scaleFactor);
var canvas = document.getElementById("drawPop.canvasOne");
var c = canvas.getContext("2d");
if (drawingView.canvasRestorePoint[0]!=null)
{
c.clearRect(0,0,canvas.width,canvas.height);
var img = new Image();
img.onload = function() {
c.scale(inverseScale,inverseScale);
c.drawImage(img, 0, 0);
c.scale(drawingView.scaleFactor, drawingView.scaleFactor);
};
img.src = drawingView.canvasRestorePoint.pop();
}
},
I'm working on a multi part html questionnaire style form that has a lot of text questions along with a few images. On questions that are images the user is selects the image, i create a canvas element and display the resized image in it underneath the file input.
if (window.FileReader)
{
var file = element.files[0];
var $input = $(element);
var $fileName = file.name;
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement("img");
img.src = e.target.result;
var dataID = $input.data("questionId");
var canvasID = "canvas_" + dataID;
$("#"+canvasID).remove();
var canvas = document.createElement("canvas");
canvas.setAttribute("id", canvasID);
canvas.setAttribute("height", "200");
canvas.setAttribute("width", "200");
var heightWidth = getHeightWidth(img);
canvas.height = heightWidth[0];
canvas.width = heightWidth[1];
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0, canvas.width, canvas.height);
var sectionID = "section_" + dataID;
$("#" + sectionID).append(canvas);
$("#file_title-" + dataID).val($fileName);
}
reader.readAsDataURL(file);
}
else
{
alert("This browser does not support image uploading.");
}
This works fine in chrome but not in safari (safari 8.x) on desktop or iOS. The problem in my code is that on Safari it returns height=0 width=0 from getHeightWidth() which gives me think the img isn't ready to be handled yet. This theory is further validated because if i change to a new picture and change back to the original it displays properly.
I'm really not sure where to start, any help debugging this would be greatly appreciated. Thanks everyone
The code assumes the image loading is synchronous, but it's asynchronous and should be assumed so even with data-URIs. If the image hasn't loaded properly its width and height attributes will be 0.
You can solve this by adding an onload handler for img, then move the code for detecting and setting size inside that handler (remember also to add an onerror handler as well in case the image file is corrupted).
I'm trying to get an image from a canvas, it worked on pc browsers, but not on mobile (I tested on an iPhone in Safari)...
Here is the code:
$('#draw').click(function() {
$('#drawing').css("visibility", "visible");
var drawing = document.getElementById("drawing");
var con = drawing.getContext("2d");
var img = new Image();
img.src = "http://www.deque.com/wbcntnt928/wp-content/dquploads/jquery_logo.png";
img.onload = function() {
con.drawImage(img, 0, 0, 250, 250);
//Generate Image
var drawing = document.getElementById("drawing");
var dataURL = drawing.toDataURL(); //Does nothing on mobile, not even an error
document.getElementById("result").src = dataURL;
};
});
Any hint of why?
I have the same issue. Tested on HTC Desire with Android 2.3, HTC One with Android 4.0 and iPhone 7s ... I run over the toDataURL() but only get "data:," as output.
According to here it's not supported by Android, dunno about iOS7 but it seems it isn't either.
Btw. is there a reason for calling var drawing = document.getElementById("drawing"); twice?