I have an local network IP camera that dumps its frames into a still JPG image (I don't know the frequency it does this). I have a test HTML document that has some JavaScript that makes an <img> element update every X ms to this still image. This creates a "fake" video.
I know how often I'm making the element update (my desired FPS) however it'll never be the same because it has to fetch the image from the source which takes extra ms.
Is there an easy & efficient way to accurately time this, to determine the real FPS?
My code:
<img id="video" src="" width="704" height="576" alt="Camera not running" />
loop = function() {
setTimeout(function() {
//Force update...
document.getElementById('video').src = '/location/of/raw/image.jpg';
loop();
}, (1000 / parseInt(fps)));
}
loop();
Note: I use setTimeout instead of setInterval so I can modify the desired FPS at any time.
Note: This is only part of the full script. I don't get the video element every loop.
I don't want to use server-side programming. I want to keep this to HTML and JS.
I'm currently working on a web application which has a page which displays a single chart (a .png image). On another part of this page there are a set of links which, when clicked, the entire page reloads and looks exactly the same as before except for the chart in the middle of the page.
What I want to do is when a link is clicked on a page just the chart on the page is changed. This will speed things up tremendously as the page is roughly 100kb large, and don't really want to reload the entire page just to display this.
I've been doing this via JavaScript, which works so far, using the following code
document.getElementById('chart').src = '/charts/10.png';
The problem is that when the user clicks on the link, it may take a couple of seconds before the chart changes. This makes the user think that their click hasn't done anything, or that the system is slow to respond.
What I want to happen is display a spinner / throbber / status indicator, in place of where the image is while it is loading, so when the user clicks the link they know at least the system has taken their input and is doing something about it.
I've tried a few suggestions, even using a psudo time out to show a spinner, and then flick back to the image.
A good suggestion I've had is to use the following
<img src="/charts/10.png" lowsrc="/spinner.gif"/>
Which would be ideal, except the spinner is significantly smaller than the chart which is being displayed.
Any other ideas?
I've used something like this to preload an image and then automatically call back to my javascript when the image is finished loading. You want to check complete before you setup the callback because the image may already be cached and it may not call your callback.
function PreloadImage(imgSrc, callback){
var objImagePreloader = new Image();
objImagePreloader.src = imgSrc;
if(objImagePreloader.complete){
callback();
objImagePreloader.onload=function(){};
}
else{
objImagePreloader.onload = function() {
callback();
// clear onLoad, IE behaves irratically with animated gifs otherwise
objImagePreloader.onload=function(){};
}
}
}
You could show a static image that gives the optical illusion of a spinny-wheel, like these.
Using the load() method of jQuery, it is easily possible to do something as soon as an image is loaded:
$('img.example').load(function() {
$('#spinner').fadeOut();
});
See: http://api.jquery.com/load-event/
Use the power of the setTimeout() function (More info) - this allows you set a timer to trigger a function call in the future, and calling it won't block execution of the current / other functions (async.).
Position a div containing the spinner above the chart image, with it's css display attribute set to none:
<div> <img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>
The nbsp stop the div collapsing when the spinner is hidden. Without it, when you toggle display of the spinner, your layout will "twitch"
function chartOnClick() {
//How long to show the spinner for in ms (eg 3 seconds)
var spinnerShowTime = 3000
//Show the spinner
document.getElementById('spinnerImg').style.display = "";
//Change the chart src
document.getElementById('chart').src = '/charts/10.png';
//Set the timeout on the spinner
setTimeout("hideSpinner()", spinnerShowTime);
}
function hideSpinner() {
document.getElementById('spinnerImg').style.display = "none";
}
Use CSS to set the loading animation as a centered background-image for the image's container.
Then when loading the new large image, first set the src to a preloaded transparent 1 pixel gif.
e.g.
document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';
While the large_image.jpg is loading, the background will show through the 1pix transparent gif.
Building on Ed's answer, I would prefer to see something like:
function PreLoadImage( srcURL, callback, errorCallback ) {
var thePic = new Image();
thePic.onload = function() {
callback();
thePic.onload = function(){};
}
thePic.onerror = function() {
errorCallback();
}
thePic.src = srcURL;
}
Your callback can display the image in its proper place and dispose/hide of a spinner, and the errorCallback prevents your page from "beachballing". All event driven, no timers or polling, plus you don't have to add the additional if statements to check if the image completed loading while you where setting up your events - since they're set up beforehand they'll trigger regardless of how quickly the images loads.
Some time ago I have written a jQuery plugin which handles displaying a spinner automatically http://denysonique.github.com/imgPreload/
Looking in to its source code should help you with detecting when to display the spinner and with displaying it in the centre of the loaded image.
I like #duddle's jquery method but find that load() isn't always called (such as when the image is retrieved from cache in IE). I use this version instead:
$('img.example').one('load', function() {
$('#spinner').remove();
}).each(function() {
if(this.complete) {
$(this).trigger('load');
}
});
This calls load at most one time and immediately if it's already completed loading.
put the spinner in a div the same size as the chart, you know the height and width so you can use relative positioning to center it correctly.
Aside from the lowsrc option, I've also used a background-image on the img's container.
Be aware that the callback function is also called if the image src doesn't exist (http 404 error). To avoid this you can check the width of the image, like:
if(this.width == 0) return false;
#iAn's solution looks good to me. The only thing I'd change is instead of using setTimeout, I'd try and hook into the images 'Load' event. This way, if the image takes longer than 3 seconds to download, you'll still get the spinner.
On the other hand, if it takes less time to download, you'll get the spinner for less than 3 seconds.
I would add some random digits to avoid the browser cache.
I am researching setting up a script that will show certain notes along with accompanying music tracks. Basically I need certain times in the audio track to trigger events. I have seen I could use the currentTime similar to the following, but I am getting hung up on a good way to make a concise function to move between frames and move back and firth if there is a rewind etc. Help's appreciated greatly!
$("#ogg_player_1_obj").bind('timeupdate', notePosition);
function notePosition(){
myVid=document.getElementById("ogg_player_1_obj");
mct=myVid.currentTime;
//SET Frame based on time???
}
function notePosition(){
//your code.
if(frame1start <= mct && frame1end >= mct) {
$(".frame").fadeOut(100);
$("#frame1").fadeIn(100);
}
//and again for every frame.
}
This works if you put every frame in a seperate element with class frame and the id frame + number.
I integrated a slider on my brothers website. He wants some preloading, so the the first image of the slide lasts longer than the rest, so the slider can load all images while the first image shows. Do you have any ideas how to delay just the first slide? I tried to find something inside the Javascript file but I dont think its a good Idea for me to work in the source.
Link: http://www.davidgoltz.de/2011/anna-bederke-actor/
Thank you!
Initially when you start set auto to 0 so it doesn't auto change.
Then after a delay (use setTimeout()) set auto to the new value.
i assume you know the number of images should be loaded. then you can set a counter and trigger auto change event;
var counter = 0;
$(".class-of-images-should-be-loaded").bind("load",function(){
counter++;
if(counter == n){ //n - number of images
//trigger your event
}
}
put a single class to all of the images and use it as the selector.
you can use "settimeout" either but if the connection is very slow, there might be unloaded images in slideshow.
*i used jQuery because you have jQuery library in your web page
I'm looking for a little help with my javascript slideshow, for which the code was used from a tutorial on the internet. I want to basically make it so when you mouse over it stops the image from changing. Also, i'd like to have two buttons at the bottom of the slideshow such as the image below.
http://imageshack.us/photo/my-images/841/slideshowexample.jpg/
<img src="/wp-content/themes/twentyten/images/slide1.jpg" name="slide" />
<script>
<!--
//variable that will increment through the images
var step=1
function slideit(){
//if browser does not support the image object, exit.
if (!document.images)
return
document.images.slide.src=eval("image"+step+".src")
if (step<3)
step++
else
step=1
//call function "slideit()" every 5 seconds
setTimeout("slideit()",5000)
}
slideit()
//--></div></script>
Thanks in advance,
Nick.
Unless you are just doing this as an exercise to learn more about JavaScript, a better option than a homegrown slideshow would probably be to use a DOM library. There's a pretty good tutorial on creating a slideshow with jQuery at SixRevisions.
There are also a number of pre-built slideshow plugins for the various DOM libraries jQuery has a bunch.
If you were to continue using your current code, to create the pause on mouseover you would first need to create a variable and store the result of setTimeout() in it.
var timer;
timer = setTimeout(slideIt, 5000); // note I just passed the function name instead
// of quoting an invocation. Using "slide()"
// creates an unnecessary eval() call.
You could then use the timer variable to call clearTimeout() in a mouseover event you attach to the the image. You would also need to attach a mouseout event to call setTimeout() again to restart the slide show. That said, this is a situation you should really be using setInterval() and clearInterval() instead of setTimeout().
You don't need the <!-- and //--> unless your expect you code to be running in ancient browsers like Netscape 1.0 and IE 2; all modern browsers understand JavaScript and don't need that hack to hide JS.