Why not animated GIF instead of animated CSS sprites? - javascript

In recent trends I've seen people animating CSS sprites using JavaScript instead of using animated GIFs?
Ex:
http://www.google.com/doodles/eadweard-j-muybridges-182nd-birthday (in fact, Google used this technique in other Doodles too)
https://everyme.com/ ('me' logo)
and many more...
Is that all just to show or experiment with technology or are there any benefits out of it. I m interested in knowing the benefits, if there. The reason I m asking is that I couldn't figure out as in both cases we need to generate the intermediate frames (mostly using tweening technique).

Control
You have no control over animated GIFs. You can't start them, you can't stop them. They just animate as soon as they load.
With sprites, you can control the animation. You can start, stop and react to browser events, pan through the animation. For example, Google Doodles usually activate when you click on them.
A nifty GIF control system can be found in the 9gag. You can start them by appending them to the DOM, and stop them by removing them and swapping them with a pre-generated "first-frame view". But that's as far as GIFs go.
Independent Instances
When you load multiple instances of the same GIF, all these instances use the same image across the page and move at the same time. If you have a row of dancing unicorns GIFs, they'd be dancing at the same time. Synchronized dancing!
But with sprites, even if you are using the same images, the animation relies on the underlying script. So if one sprite is animated by one script and another by another script, both animations can run independently, and differently from one another.
This saves you from creating another GIF and it's easy to modify since you are only changing the script.
Ensuring smooth animation
Animated GIFs just animate while loading, and when the internet is slow, the animations freeze up until more of the image gets loaded.
In contrast, the advantage of sprites is you can pre-load them, ensure all images load beforehand. This makes sure that the resources used for that animation are already loaded prior to animation to make sure it animates as smooth as possible.
However, GIFs are still images. You can dynamically load them off the DOM and listen for a load event before you append them to the DOM.
Partial rendering
With PNG sprites, you can do "partials" in the animation, breaking an animation scene to parts. For example, when a character stands still, but the arms are waving. You don't need to animate the entire character, or the entire scene. You can place an element depicting the sprite of the character's body in a "freeze" state while the arms are a different element that is animating. This conserves space and size of the sprite sheet. A good example for this was the 2012 Mother's Day Doodle by Google.
In contrast, most of the time, every frame in a GIF animation is whole image, and animates whether or not anything in it moves. The more frames, the bigger the size of the GIF.
GIFs just don't scale
GIFs were meant for icons. The ratio of file size to image size don't scale up that well in GIFs as compared with PNG and JPG.

On top of Joseph the Dreamer's answer...
As far as I know, or atleast it used to be that, GIF files are NOT true colour, another reason to use a JPGs/PNGs as a css sprite.

Related

controlling the time to load and play animated gifs

I have a slide with many animated gifs. Every slide contains an animated gif.
The effect I am trying to achieve is having the animated gifs play according to the timeline I created in photoshop and from the first frame to last when in view.
My issue is the animated gifs will start from the middle of the timeline instead of from the first frame when it is active and in view. I reckon it could be due to the loading time? I have tried increasing the time for the first frame and last frame of each slide but to no avail.
Is there a way to control the time to load and play the animated gifs when it is in view? is it something that needs to be done in javascript or jQuery?
From my point of view, CSS Sprites will give you better support that you wanted in your animation. Most important thing you need is to control over animation.
As you don't have any control over animated GIFs. You can't start them, you can't stop them, only thing they just do is to animate as soon as they load.
On the otherhand, with sprites, you can control the animation. Most importantly you can start, stop and react to browser events, pan through the animation.
As reference you can see Google Doodles which only activates when you only click on them.
For active reference, you can see the blog which might inspire you to use CSS Sprites.
https://itnext.io/creating-css-animations-using-sprite-sheet-47e2b7a3793c
Again, it's only opinion. Decisions is yours which one you will use for animation.

I'm not sure when pre-rendering canvas is appropriate! (my example in description)

I'm pretty new to HTML5's canvas, and have been reading about pre-rendering canvas images to optimize performance...However, I'm not sure what pre-rendering is actually going to help versus when its just extra code I wouldn't need...
My project requires that I have a canvas, which will contain about 5 images of my web dev projects. These images will be revealed via the scroll distance, and using a wipe effect as shown below.
Would using a 5 off-screen canvas' to pre-load the 5 or so images beforehand be optimal in this case? I think it might be since the effect is dependent on scroll, so the user could repeatedly scroll up and down, and having pre-rendered canvas images may lower the computation required to render and draw the images...
Wipe Start
Wipe During

Stutter when animating / moving sprite with JavaScript

I'm attempting to create an animation by moving a sprite image across a div. The sprite image contains each frame of the animation. The size of the "canvas" is 600px by 624px. Each frame on the sprite sheet is positioned every 600px and I'm moving the image 600px at a time.
Here is what I have so far...
voyced.com/crownacre/www/demo/sprite.html
I'm using the following JavaScript to move the image across the screen...
(function myLoop(i) {
setTimeout(function() {
defImg.css({
right: '-=600'
});
if(--i) myLoop(i); // decrement i and call myLoop again if i > 0
}, 60) // delay ms
})(114); // number of frames in the sprite
I've used several sprites all floated left as the total width of sprite sheets in 69000px, which causes even more issues if I use just one image! Hence why I have 4 at the moment.
So... The problem I am having is that the animation pauses briefly several times. It seems fine in Firefox (for me), but you notice it in Chrome and you can't miss it in IE.
It also always stutters every 16200px, making me think this is related to moving 1 sprite into the next on the screen.
Ideas please people?
Thanks in advance!
Have you tried using a sprite animation plugin?
http://www.spritely.net/
Does what you want, seems to run well on their demo.
Let me first say: The huge images you're trying to display as a sprite isn't exactly what sprites/animations are used for. You can better look into a real <canvas> solution (especially when looking at your animation), but that would require some more complex JavaScript skills.
Anyway, the problem with the stutter is because you're using several images that are all floated to the left, and position the slider with the right property. Each time another image needs to be displayed, a stutter can be noticed. This might have something to do with the browser engine, needing to paint the actual image (which is hard, since they're pretty big).
So, instead of using several images, you could also use one (take note, you might want to make this a .JPG or .GIF since they tend to be more compact than .PNG) and use actual CSS sprites with background-position.
Here's an example that uses your code, and one single image. Good luck!
Thanks again for the feedback guys. I used a combination of your tips that have helped me solve the issue I was having.
Spritely has helped immensely. Essentially it is doing the same as what #marcoK suggested, and adjusting the background-position property. This plugin also provides a fool proof way of controlling each frame of the sprite, as well as creating callbacks when it reaches a specified frame - awesome!
The other issue was the huge sprite. Mobile safari won't allow anything larger than 3MP so the max size I could make the image was 4800x624. I have 15 of these each as a separate animation that calls the next when it reaches the last frame. I was very sceptical about this working smoothly, but it does, and in all browsers.
I'm not overly happy with the number of request it makes but after optimising the pngs the file size isn't too bad if I add a pre-loader.
Really pleased with the outcome... http://www.crownacre.voyced.com/ and one more reason not to use Flash!

Count gif replays

Is it possible to count how many times an animated gif has played with javascript/jquery?
Nope, that's not possible.
However, you could create an interval using setInterval with the duration of the animation which increases a counter.
As #ThiefMaster says, You can't do this with a GIF anim.
However, you can achieve what you want using a javascript animation.
Rather than saving the frames of the animation in a GIF anim, save them in a single PNG file, in a row (ie so it looks like a reel of film) either horizontally or vertically.
Display the image in an element on the page that is sized so you can only see one frame of the animation at a time, and then use Javascript to adjust the CSS offset of the image at regular intervals using setInterval or setTimeout.
This technique is known as CSS Sprite animations. It's easy to do, and it's basically the standard way of doing spot graphic animations on the web now (GIF anims are soooo 1998).
Google will give you plenty of resources to help you find out more: https://www.google.com/search?q=css+sprite+animations
You might also want to read the accepted answer to this question: Why not animated GIF instead of animated CSS sprites?

Efficiently loading hidden/layered images in web page

I have a layered div component which displays a successive series of large kb images by slide-animating away the top image to reveal the next image below. I'm trying to understand how best to approach this.
Approach 1:
layer a number of divs on top of each other, each with an image assigned as background, and slide away the divs as needed.
Will the hidden divs load their images on page load, or only when they are revealed? Is this browser/client specific behavior? Do all images (jpegs, pngs) behave the same way in this regard?
Approach 2:
Use only two divs- One that handles sliding, the other that will load and reveal the next image.
In this case, is it possible to pre-load the next image, so that the javascript isn't slowed down when the next image is revealed?
Thanks- and if anyone has other ideas, I'd love to hear them.
Your first approach, even if the images are 'hidden' via CSS, will load all images by all browsers via HTTP requests. Your second approach or some variant of it is probably better.
I'd recommend using AJAX to pull down each image as you go. It's definitely possible to preload the images.
You may want to consider existing slideshow/lightbox type of plugins for jquery or javascript. It's been done so many times you will sort of be recreating the wheel (unless it's more of a learning experience thing)..
Here's an interesting example of preloading with callbacks to alert you when it's ready. Maybe a good one to adapt?
http://binarykitten.me.uk/dev/jq-plugins/107-jquery-image-preloader-plus-callbacks.html
The first approach certainly degrades better. It will leave the images available and visible if viewed on a CSS-challenged browser. But that comes at the cost of having to pull down all the images from the get-go. The second approach is lighter on the initial hit, at the cost increased code complexity swapping images in/out.
You can definitely pre-load images with Javascript. just create an image object and set its source to whatever you want, which will automatically trigger downloading of the image. It doesn't have to be inserted into the DOM or visible to the user to do this.
Hidden divs SHOULD load their content automatically, whether they're visible or not. I can't think of any PC-based browsers that wouldn't do this, but I'd hazard a guess that some browsers intended for resource-limited devices (cell phones for one) might optimize things and delay loading contents until the container's made visible, to save on network traffic.

Categories

Resources