Modifying flipbook jquery to load faster - javascript

I am using the Flipbook jquery plugin with a large png image sequence. I emailed the creator of the plugin and asked if there's any way to create some sort of "loader" or allow it to load in chunks and start playing after a certain amount of images are loaded. He responded with the following:
This should be possible and I was thinking of doing this but it wasn't needed at the time.
In the flip book code the shouldStartAnimation function determines if the animation should start by incrementing a counter and checking that counter against the total number of frames. When all the frames have been loaded the timer starts which flips the frames. This code could be changed so the timer starts after half the frames were loaded or something. It could also get really fancy and figure out how long each frame is taking to load and then guess how many frames it needs to let load before it can start playing the sequence so all the frames are loaded by the time it needs them.
Unfortunately I don't have time to make these changes myself, but feel free to modify this code for your needs :)
https://gist.github.com/719686
Unfortunately I don't know enough javascript to get this done, and I don't know exactly how much work this would be for someone who did. I am just hoping someone here might have some more helpful info or advice to help me figure this out (or, obviously, if this is easy enough for someone to just do, that would be amazing).

Add one more option default, the following, make sure to have proper "comas" in right places.
'loadbeforestart': 10, //start animation when 10 frames are loaded
And edit a variable in the following function, replace variable "end" with "loadbeforestart"
function shouldStartAnimation(){
//console.log('pre: '+imageName(i));
preloadCount += step;
if(preloadCount >= loadbeforestart){
setTimeout(flipImage, holdTime);
}
}
This should do the trick, I think*

Related

Simulate timeout in Phantom JS

We are taking screenshots using PhantomJs, which works quite well for us. Now we face the challenge that some of the websites we take screenshots of have animations when the page loads. We can of course use a simple timeout of, let's say, 5 seconds, but we surely don't want to wait actual 5 seconds idling for each screenshot.
Is there a way to "simulate" a screenshot, i.e. to tell Phantom to internally fast forward 5 seconds while actually, from the outside, no time passes?
No, there is no way to fast forward the time 5 seconds.
As a workaround, you might want to take a screenshot every second and see if it changes with a timeout at 10 seconds for example. The comparison of the images can be done in various ways like actual byte by byte comparison or invocation of some image library that can actually compare the image data itself where you can set a match even when the images are only 99% equal.

How do I cascade start multiple gifs?

I have a gif of a candle with an animated flame. My webpage will show a few of these gifs in a row. It would be much more realistic if all the gifs didn't start at once after the page loads (otherwise I get a line of 'synchronised' candles).
I can create multiple gifs with different flame animations and then randomise which ones get shown but this will take extra bandwidth and will add an extra level of complexity.
Is there a way to maybe cascade start the gifs? i.e. start each one after a random amount of time in order that they are out of synch and look a bit more realistic?
Maybe using jquery? Or simple javascript?
Many thanks
You can't do that.
If you place the same image on multiple places, it's going to always look the same.
You could edit the image and change the order of the frames within the gif, save and repeat this a few times, and then load the gifs, but this will only work if the images are already loaded (cached) on your browser.
If this is the first time you load the page, it could just happen that an image will be loaded exactly when another image started from the first frame of the loaded image, so it will look as if they are in sync.
You could load the images using setTimeout but this will have the same problem as described above when the user first enters your page. You can delay the request for loading the file, but you have no control of the speed in which the file will be downloaded and therefor no control on when exactly the first frame will start playing.
If I were you, I'd try creating a big sprite of different images, each starting the animation from a different frame. There will be only one request and all animations will play together, making sure frames are never in sync.
When displaying the images on the site, make sure to properly show only the part you want for each image. This will give you the effect of flames burning at random times.

How to stop an animated gif from looping

I have an animated gif in an img tag that I start by rewriting the src attribute. The gif was created, though, to loop and I only want it to play once. Is there a way, with Javascript or jQuery, to stop an animated gif from playing more than once?
I was having the same problem with an animated gif. The solution is rather simple.
Open the Animated gif in Photoshop.
Go to the Window tab and select timeline(if the timeline is not already open).
At the bottom of the timeline panel, you will find an option, which says "Forever".
Change that to "Once".
Go to File> Export> Export for Web and save it as a gif.
That should do it.
can you find out how long the gif takes to loop once?
if so then you can stop the image like this:
pseudocode:
wait until the end of the image (when it is about to loop)
create a canvas element that has a static version of the gif as currently displayed drawn on it
hide gif
display canvas element in a way that makes it look like the gif froze
javascript:
var c = $("canvas")[0];
var w = c.width;
var h = c.height;
var img = $("img")[0];
setTimeout(function () {
c.getContext('2d').drawImage(img, 0, 0, w, h);
$(img).hide();
$(c).show();
},10000);
jsfiddle
edit:
I forgot to add reference to the original answer that I took this from, sorry
Stopping GIF Animation Programmatically
that one doesn't address the time factor you need for only one loop
Also, it has been mentioned that this approach is problamatic in certain cases (It actually didn't work when I try it in firefox right now...). so here are a few alternatives:
mentioned by Mark: edit the gif itself to avoid looping. this is the best option if you can.
but I've run into cases where it was not an option (like automated generation of images by a third party)
instead of rendering the static image with canvas, keep a static image version and switch to stop looping . this probablyhas most of the problems as the canvas thing
Based on this answer, it's kinda expensive, but it works. Let's say a single loop takes 2 seconds. At a setTimeout after 2 seconds kick in a setInterval, that would reset image source every millisecond:
setTimeout(function() {
setInterval(function() {
$('#img1').attr('src',$('#img1').attr('src'))
},1)
}, 2000)
again, probably just a proof of concept, but here's demo: http://jsfiddle.net/MEaWP/2/
Actually it is possible to make a gif to stop after just one iteration or any specific number of iterations, see an example below (if it is not already stopped), or in jsfiddle.
To do that the gif must be created with number of iterations specified. This could be done using Screen to Gif, it allows to open a gif or a bunch of images and edit it frame by frame.
This solution also allows you to reset the animation by imgElem.src = imgElem.src; but this does not work in MS IE/Edge.
Jurijs Kovzels's answer works in some condition but not in all.
This is browser-dependent.
It works well with Firefox. But In Google Chrome and Safari, it does not work if the gif is on the same server. The example he provided works because the gif is on the external server.
To restart gifs stored on the internal server, using Google Chrome and Safari, you need extra steps to make it work.
const img = document.getElementById("gif");
img.style = "display: none;";
img.style = "display: block;";
setTimeout(() => {
img.src = img.src;
}, 0);
This is inspired by this answer.
Not sure if this is the best way to respond to everyone and have it appear after all the previous answers and comments, but it seems to work.
I don't have much control over the gif. People post whatever gif they want as the "thankyou.gif in their account directory and then the ThankYou code runs whatever they've put there when a comment is submitted to a form they've posted. So some may loop, some may not, some may be short, some may be long. The solution I've come to is to tell people to make them 5 seconds, because that's when I'm going to fade them out, and I don't care if they loop or not.
Thanks for all the ideas.
I know I am pretty late here but..here it is...
I don't know if you would go to this length but let me share a trick.
Open the GIF in Macromedia Flash 8(it has deprecated since then), Export the GIF as Animated GIF. You will have to choose the file location. After that you would receive a dialog box with settings. In that, add the number of times you want the animation to happen. Click OK. Problem solved.

Is there a way to check how much of the picture has been loaded, in pixels, from the top?

The heading sums is all. Though, the case is where I have a long (20x2000px) picture as a sprite for thumbnails. It would be nice if I could start showing the sprite only for the thumbnails that already have required-part of the sprite loaded, and show loader in the meantime.
All I need is to know how much of the picture has been loaded in pixels from the top (supposing that it is not progressive). I thought of using file size to estimate that, though that would be very inaccurate.
The main question everyone is having - why to do this at all?
There is a page that displays somewhat 100 thumbnails. It would be a nice thing if this page had a sprite of those thumbnails generated in the descending thumbnail order.
Such page already exists. The screenshot is attached. User can see a gray placeholder while the sprite is being loaded. I want to display the thumbnail only when the required part of the sprite for that thumbnail is already loaded.
#Guy Sounds like a theoretical question then... Per your comment on the answer below, if you're loading 10MB 'sprites' you're doing it wrong.
No, there is nothing wrong about it if this can be achieved. That would reduce the number of calls by 100 every time the page is being called. That is a remarkable speed improvement even if everything is cached.
I see what you're trying to do, but in short, you can't. Counting pixels in JavaScript, if it possible at all (maybe with canvas? I don't think so though) would just be unreasonably resource-consuming. Loading all the images separately (i.e., not as one sprite), however, will give you exactly the effect you're looking for as a default on most browsers, albeit at the cost of more requests.
The solution? Use a Content Delivery Network (CDN), so the browser can fetch all 100 images at the same time, without necessarily putting the strain on your own server.
EDIT:
After some additional searching, I found what looks to be a solution here and is similar to a solution provided here. The basic idea is to make an AJAX request and monitor the progress.
If I'm understanding you correctly, you want to avoid that brief period of time that a page is loading (or after a even occurs) where images haven't finished transferring and don't yet appear where they should.
The problem I think you're going to run into (if this is a scenario where the page is loading) is that you're waiting for your placeholder image and the sprite to come across the wire. By the time your placeholder gets over, your sprite may have gotten there already or be milliseconds behind, and you haven't avoided the situation described above.
If you're dealing with a mouseover event or something similar where the sprite is requested for the first time, you can pre-load the sprite image by calling it via JavaScript when the page loads, so it'll already be cached and ready when the event fires.
I already have a theoretical solution. Before I start working on it, it would be nice if anyone can tell me if there is any major fault in my thinking.
The image is generated server-side, screenshot after screenshot. Therefore, after every screenshot merged into the sprite I can save the thumbnail size information to the database along with the corresponding entry.
Once user lands on the page, I will keep checking how many bytes of the sprite are loaded, loop through every entry that is pending to be displayed, check if the value is greater or equal to the entry "weight" and display or continue the loop appropriately.

Animated gifs to signal that something is computing ? what are better alternatives?

I have written some javascript whereas if you click on some divs those expand with some data.
it takes a few seconds to populate the divs.
So to avoid users getting frustrated I have done the following:
if user clicks on div then add animated gif (moving bar,...) on div
when data is ready event is triggered and animated gif is removed
can somebody suggest a better approach or pattern ?
since I don't know how expensive for the browser to render animated gifs...
thanks
Rendering GIFs is not very expensive in terms of performance. Displaying animated GIF loaders etc. is definitely better than doing nothing on waiting time. It is much more important to users to know that something is happening than finishing a split second earlier.
The best thing would be to progressively reveal information as you receive it, but in the final form from the beginning. This is easier said than done. Browsers do half of this by rendering different page elements as they are received but fail at the other half by moving things around as formatting information is received and by making you think you can do something before you are actually allowed to do it.
The second best thing would be to have an animated gif that gives some indication of how long the process will take. Many systems fail utterly at this and have been compared to a car navigation system that says "Estimated Time of Arrival 10 minutes .. 8 minutes ... 2 days ... 1 second ... 3 hours."
Because of those failures, I would say that what you are doing is the right thing.
As long as the GIF itself is small and properly preloaded, that's a fine way to go.

Categories