Chrome / Firefox Cached Images Issue - javascript

I'm having trouble when preloading images and creating elements on the fly. The script loads a list of image URLs, creates canvas elements etc.
The problem is that on subsequent "soft" refreshes or submission of the same URL the preload loop isn't initiated, so the canvas elements etc. are not created. I'm pretty certain this has something to do with resource caching - however - why the script isn't iterating through the image URL list and building the DOM as expected I'm not sure... Here's an example
The JavaScript on the page is optimised output, but the preload loop looks like this:
// Images array
var images = [];
for (var i = 0; i < l.length; ++i) {
// Create canvas element
var canvas = document.createElement('canvas');
// Canvas element properties
canvas.width = l[i].w;
canvas.height = l[i].h;
canvas.style.display = 'none';
// Image element + mouse over event
images[i] = document.getElementById('i' + i).getElementsByTagName('img')[0];
images[i].addEventListener('mouseover', function() {
handleCanvas(this);
}, false);
// Push canvas into DOM
images[i].parentNode.insertBefore(canvas, images[i]);
// Preload item from processed images list
var image = new Image;
image.src = l[i].i;
}
I'd prefer not to resort to headers or "URL?random=37436464" type fixes if possible. Tested on nightly versions of Chrome and Firefox on Ubuntu 12.10.

After further investigation (testing in IE9) it appears the issue was cause by asynchronous loading of the JavaScript and lagging variable initiation.

Related

html 5 canvas: using draw image in game makes loop very slow

i am making a game based on draw images and clear it every some part of second.
i started with:
var peng = new Image();
and then:
peng.onload = function() {
context.drawImage(peng, pengXPosition, pengYPosition, pengWidth, pengHight);
};
and in the loop:
var i=0;
function pengMoveRight(){ i++;if(i==1){peng.src = 'images/1.png';}else if(i==2)
{peng.src = 'images/2.png';} else if(i==3){peng.src = 'images/3.png';}else if(i==4){
peng.src = 'images/4.png';}else if(i==5){peng.src = 'images/5.png';}else if(i==6){
peng.src = 'images/6.png';i-=6;}}
when i run it it works well on IE but on chrome and mozilla it`s too slow and the character is about to disappear .. i used setinterval(); once and window.requestAnimationFrame(); once and both of them cause the same problem.
what should i do to make it smooth move?
here is the full script http://mark-tec.com/custom%20game/
Instead of changing the source, try to create several Image objects instead. That way, the drawImage call can always use a pre-loaded image.
You need to preload all the images or use the sprite method (all images packed into a single sprite) in order to avoid the initial delay caused by the image loading only when it's needed.
However, after that initial problem, your example should run fine once all the images are cached.

Save Canvas between pageloads

Ive been trying to make the canvas save between page refreshes using html5 local storage, but the canvas always gets back to blank when i refresh the page.
HTML
<canvas onload="loadCanvas()" onClick="canvas(event)" id="myCanvas" width="400" height="400">
Your browser does not support the canvas element
</canvas>
Javascript:
function saveCanvas() {
var c = document.getElementById("myCanvas"),
ctx = c.toDataURL();
if (typeof (localStorage) !== "undefined") {
localStorage.setItem('myCanvas', ctx);
} else {
document.getElementById("save").innerHTML.dataURL = "Local Storage not supported";
}
}
function loadCanvas() {
var image = localStorage.getItem('myCanvas');
document.getElementById('myCanvas').src = image;
}
saveCanvas function gets called when something has been drawed in the canvas
Anyone knows what the problem is?
It has been solved, onLoad did not work in canvas
localStorage can only save so much, ie. in most browsers 5 mb and in others less.
Another caveat is that each char stored takes 2 bytes due to unicoding so the storage is in reality only half of this in the practical sense. There is no guarantee about size as this is not defined by the standard - 5 mb is only a suggestion so browsers can use any size.
You are getting the image as a PNG as this is the default format of toDataURL(). If the produced data-uri is too large (which is likely here as base-64 adds 33% to the size + a small header) the save will truncate or fail depending on the browser.
This is most likely (as you don't state size of canvas or the resulting data-uri) why your canvas is blank when you try to reload the data-uri as it would be invalid.
You can try to save as JPEG instead:
dataUri = c.toDataURL('image/jpeg', 0.5); /// 0.5 is quality, higher is better
If this does not work then you will need to look into other local storage mechanisms such as Indexed DB (where you can request a storage quota) or File API (but this is only supported in Chrome at this moment). There is also the deprecated Web SQL which will be around for still a while.
Update
Also try to move your onload from canvas element to window:
window.onload = function() {
var image = localStorage.getItem('myCanvas');
document.getElementById('myCanvas').src = image;
}
Note: you cannot set a src on a canvas element (as the ID from your code here suggest as well as your example code show). You need an image element for that. When you set a src on an image you also need to use the onload handler on the image, so an example could be:
window.onload = function() {
var img = new Image;
img.onload = function() {
var ctx = document.getElementById('myCanvas').getContext('2d');
ctx.drawImage(img, 0, 0);
/// call next step here...
}
img.src = localStorage.getItem('myCanvas');
}
Usually I suggest (and others did too in this thread) people store their drawings as points and shape types in an array as objects which then is serialized to a string which you instead store in localStorage. It involves a little bit more code in the render stage (which you need anyways to update canvas when it is blanked for some reason) but is worth it.

what is best to use canvas or img for frequent updates?

I have a javascript timer.
It refreshes the img src on a 200ms interval.
I have taken a look at the canvas object. I am unsure whether it is recommended to use the canvas instead of the img element?
I am running tests on both and cannot see any differences in performance.
This is my code for using the timer/img:
This is my code:
var timer4x4
var cache4x4 = new Image();
var alias = 'test';
var lastUpdate = 0;
function setImageSrc4x4(src) {
live4x4.src = src;
timer4x4 = window.setTimeout(swapImages4x4, 200);
}
function swapImages4x4() {
cache4x4.onload = function () {
setImageSrc4x4(cache4x4.src);
};
cache4x4.onerror = function () {
setImageSrc4x4("http://127.0.0.1/images/ERROR.jpg");
};
cache4x4.src = null;
cache4x4.src = 'http://127.0.0.1/Cloud/LiveXP.ashx?id=' + createGuid() + '&Alias=' + alias + '&ReSync=' + reSync;
reSync = 0;
}
*nb will add canvas code in a bit
I am streaming images from my client desktop PC to my web server. I am trying to display as many images (FPS) as possible. The image is a container for 4 smaller images. Stitched up on the client and sent to the server.
I have Googled and it says if doing pixel manipulation and aniumation use canvas.
But, I am just doing animation.
Thanks
The canvas element was designed to draw / edit / interact with images in it. If all you do is display the image, then you don't need that and a simple img is the semantically correct choice (with the added bonus of being compatible on more devices).
In both cases, the performance will be similar (if not the same) because the only thing to happen is that the image is downloaded.
While performance-wise you won't notice much of a difference, since you still cannot fully rely on HTML5 support yet, it is probably best to go with the img-solution for now.

JavaScript: Preloading images function - Usage, DOM ready & SEO?

With the help of Google I've written a small preloader script:
var i = 0;
function preloader() {
imageObj = new Image();
images = [
'some/image1.jpg',
'some/image2.jpg',
'some/image3.png',
'and.png',
'so.jpg',
'on.png'
];
for (i = 0; i <= 20; i ++) {
imageObj.src = images[i];
}
}
This function must be called in the head of my HTML file for maximum effect, right? Do I really need to declare var i = 0;? How can I fire another function once the preloading is complete?
Also, I would like to ask how to implement this function in running websites. Let's say I have a page that has 100 img tags. I guess I have to copy and paste the source into the images array by hand, right? Because to do that with a loop, the DOM needs to be ready which again means that the images have already started loading?
Does preloading affect SEO?
If there is a better jQuery way of preloading I would be ok with that.
Because you're assigning the image SRC to the same variable, the each new request will cancel the previous because it has not completed loading.
You can use an array for this as well:
imageObj = [];
...your code...
for (i = 0; i < images.length; i ++) {
imageObj[i] = new Image()
imageObj[i].src = images[i];
}
No, this will not affect SEO because the scrapers are looking at the TEXT of your page, not the images. You can run this before the DOM is ready because you're not manipulating the DOM - all images are in memory.
jQuery is simply made of JavaScript and does not really have anything that would speed the efficiency of this simple block of code.

Images not being drawn on HTML5 canvas everytime

I'm working on a web app with which users can construct a mesh containing simple objects (rectangular shaped) that can hold text and/or images. Users can create as many of these objects as they like, and in each object that can hold an image, upload one of their own. The app is online if you'd like to test it: goalcandy.com (use demo#demo.com / demo for the email and pswd fields to log in).
Once they finalize their work, they can convert that mesh to PNG. This is done by first drawing everything that's on the mesh on an HTML canvas, which is afterward converted to a PNG image, locally.
When needing to draw the array of existing images onto the canvas, I first have to preload them, which I do like this:
query = []; // array with paths to the image
var count = query.length,
images = [],
loaded = 0;
for (i=0; i<count; i++) {
images[i] = new Image();
images[i].onload = function(){
loaded++;
if (loaded == count)
drawOnCanvas();
};
images[i].src = query[i];
}
function drawOnCanvas() {
// draw the images onto the canvas
}
The problem with all of this is that on a slow, "tired" computer, the PNG sometimes turns out blank in the spaces where some user-uploaded images are supposed to be, because the images don't get drawn onto the canvas. As if they haven't finished downloading. On a good, fast computer, this doesn't happen. How can I solve this, and why does it happen? Considering that I've already attached a handler for the "load" event, I don't see the logic...

Categories