6

I'm trying to look for an example of code that allows the user to animate a gif on mouseover and pause when mouse out. I've seen many tutorials talking about this but I want a different effect.

I noticed that most gifs "reset" when on mouse out. That is, either the gif is covered with a generic image or the animation reverts back to the start. What I would like to achieve is a more seamless "pause" that allows you to start where you left off without using a placeholder image. Similar to the example on this page:

http://www.valhead.com/2013/03/11/animation-play-state/

Notice how when you put the mouse over the image, the animation just pauses without replacing anything, and resumes otherwise.

I don't know if it's possible with a gif because this example is using basic css shapes, but there has to be some way to pause the gif on mouse out and resume on mouse over without covering the image on a looping animation? If not is there a way to use a movie file that pauses on mouse over and plays where it left off when you put the mouse over it?

Thanks!

EDIT: Thanks to @brbcoding and his genius, this issue was solved! Details on the solution can be found either in the posts below or on his blog post: http://codyhenshaw.com/blog/2013/12/17/faux-animated-gifs-with-css3-keyframes/

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
XavierTheGreat
  • 287
  • 1
  • 4
  • 17
  • 1
    It is not using gif.It is using CSS3 – Zword Dec 17 '13 at 20:41
  • The tutorial you've linked is about CSS animation, not about GIF. – Pavlo Dec 17 '13 at 20:42
  • 2
    AFAIK you cannot do anything to effect animated gifs in css. You can use css animations to *emulate* animated gifs however and achieve this effect. – Zach Lysobey Dec 17 '13 at 20:42
  • I'd break your gif into separate frames and then use keyframes to animate it. Then you can stop wherever you want. – brbcoding Dec 17 '13 at 20:42
  • 2
    *I don't think OP was trying to represent that link as being an animated .gif, but was using it as an example of the effect he is trying to achieve* – Zach Lysobey Dec 17 '13 at 20:43
  • Here is the codepen url which the site you refrenced to is providing: http://codepen.io/valhead/pen/91c4b0f93364fa25d7eca2c85140654b – Zword Dec 17 '13 at 20:44
  • "I noticed that most gifs "reset" when on mouse out." I bet it is a browser dependend behaviour, because I don't see that happening in the linked demo. Edit: wait! gif don't "reset" they just loop regardless of the pointer. – Theraot Dec 17 '13 at 20:48
  • @Theraot I bet that he is talking about *other* examples including actual `.gif`s, as I see that same behavior on sites which use that effect (but cannot remember which one(s) offhand). The linked demo is *not* a `.gif` at all, and should work the same in all modern browsers. – Zach Lysobey Dec 17 '13 at 20:53
  • @ZachL I think those are CSS animations, like the logo of [davidwalsh.name](http://davidwalsh.name/demo/sheen-effect.php). – Theraot Dec 17 '13 at 21:02
  • @Theraot yes, as noted in several comments above, the *linked demo* uses CSS animations, *not* `.gif`s. I was pointing out that I *have* seen sites which display animated gifs like OP is describing, where they are static images, and on hover they are swapped out for a cooresponding `gif`. – Zach Lysobey Dec 17 '13 at 21:26
  • Zach is completely right. I too have seen these "special gifs" that pause and resume on hover without replacing images. Also like Zach said I only used the CSS link as an example, I am very aware that it's CSS, which is what I said in my OP. I just used that as an example as there was no other way I could show you guys what I meant. I wish I had better links to show and I apologize for any confusion. – XavierTheGreat Dec 18 '13 at 06:53

2 Answers2

17

So, I thought about it for a bit... You could do something cool like this:

First, break your gif into multiple images, then animate them with css keyframes.

#faux-gif {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    margin: auto;
    background-image: url(http://i.imgur.com/E2ee6fI.gif);
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-position: center;
    width: 300px;
    height: 300px;
    /* animation: giffy 0.5s infinite linear; */
    /* no fade between frames */
    animation: giffy 0.5s infinite steps(1);
}

#faux-gif:hover {
    animation-play-state:paused;
}

@keyframes giffy {
    0%   { background-image: url('http://i.imgur.com/E2ee6fI.gif'); } 
    15%  { background-image: url('http://i.imgur.com/JIi0uul.gif'); }
    30%  { background-image: url('http://i.imgur.com/owNGnNN.gif');}
    45%  { background-image: url('http://i.imgur.com/2Ii6XOz.gif'); }
    60%  { background-image: url('http://i.imgur.com/ZmQBrQ5.gif'); }
    75%  { background-image: url('http://i.imgur.com/iAsfHyY.gif'); }
    90%  { background-image: url('http://i.imgur.com/AJwRblj.gif'); }
    100% { background-image: url('http://i.imgur.com/fx5wUNY.gif'); }
}

DEMO

JavaScript Version... Not tested very thoroughly, but this would be the basic idea.

window.onload = function() {

    function FauxGif(element, frames, speed) {
        this.currentFrame = 0,
        this.domElement   = element,
        this.frames       = frames || null,
        this.speed        = speed  || 200;
        this.interval;
        this.init();
    }

    FauxGif.prototype = {
        init: function() {
            // set the first one to the first image
            console.log(this.frames[0])
            this.domElement.style.backgroundImage = "url(" + this.frames[0] + ")";
        },
        pause: function() {
            clearInterval(this.interval);
        },
        resume: function() {
            var that = this;

            that.interval = setInterval(function(){
                that.currentFrame < that.frames.length - 1 ? that.currentFrame++ : that.currentFrame = 0;
                that.domElement.style.backgroundImage = "url(" + that.frames[that.currentFrame] + ")";
            }, this.speed);
        }
    }

    var frames = [
                    'http://i.imgur.com/E2ee6fI.gif',
                    'http://i.imgur.com/JIi0uul.gif',
                    'http://i.imgur.com/owNGnNN.gif',
                    'http://i.imgur.com/2Ii6XOz.gif',
                'http://i.imgur.com/ZmQBrQ5.gif',
                'http://i.imgur.com/iAsfHyY.gif',
                'http://i.imgur.com/AJwRblj.gif',
                'http://i.imgur.com/fx5wUNY.gif'
            ]

var elem = document.querySelector('#faux-gif'),
    gif  = new FauxGif(elem, frames);


elem.addEventListener('mouseenter', function(){
    gif.resume()
});

elem.addEventListener('mouseleave', function() {
    gif.pause();
});
}

DEMO

brbcoding
  • 13,378
  • 2
  • 37
  • 51
  • Interesting! This is something close to what I was thinking. In fact this is almost EXACTLY what I was talking about. However I noticed that the codepen doesn't work in firefox. Is there maybe an alternative fallback on this? Also is there a way to have the image start out paused and play when on mouse over? Kind of the reverse in what is achieved in the code pen, but keeping that pausing functionality. Really appreciate all of you guys looking into this! – XavierTheGreat Dec 18 '13 at 06:42
  • 1
    Hmmm... I don't know if I know of a way to make it work cross-browser, other than some js. Perhaps you can just create some kind of swapImage() function which does the same thing (just set the background image). I'll add a function in the morning when I'm back at the computer though. Same thing with reversing the operations. You'll need to do that with JavaScript I'm afraid. – brbcoding Dec 18 '13 at 06:46
  • Javascript is fine if it's possible. Like I said before, don't sweat too much on it if it can't be done. I didn't even think this was possible so you guys are already blowing my mind haha. Please take your time! – XavierTheGreat Dec 18 '13 at 06:48
  • Amazing, best of luck to you then when you take another look into this. P.S. - Totally just bookmarked your blog and following you on twitter! – XavierTheGreat Dec 18 '13 at 07:03
  • Extra credit (lol) - Also not necessary but perhaps there can also be a way for the images to swap into each other without fading? I saw this older post on a similar question. http://stackoverflow.com/questions/15469036/css3-animations-hard-blink-no-fade-inbetween-frames If it's not possible no worries, just an aesthetic request here! Thanks again! – XavierTheGreat Dec 18 '13 at 07:30
  • 1
    Still haven't had a spare moment to look at the js, but you can remove the fade by just changing the `animation: giffy 0.5s infinite linear` to `animation: giffy 0.5s infinite steps(1)`. – brbcoding Dec 18 '13 at 20:45
  • 1
    @XavierTheGreat, added a js version. You'll want to test it, I just wrote it really quickly. Also, it'd be in your best interest to pre-load the images as well. You'll probably see blank frames if you don't. – brbcoding Dec 19 '13 at 14:43
  • Nailed it! Thanks so much for the "faux firefox fallback!" This will definitely become useful for those with iffy browsers. You're a lifesaver! – XavierTheGreat Dec 19 '13 at 19:01
  • This is a fantastic solution. I just want to point out that it not only does one image swap, but it performs an image swap for each and every frame. It's no longer a gif animation. It's a sprite full of static images swapped for every frame. That's shouldn't detract from the answer though. As I posted, this is fantastic. – Scott Dec 21 '13 at 19:21
  • hi @brbcoding, thanks for the JavaScript code. It's very helpful. However, what I really want to do is to match the timing of the images to music, so the interval varies from frame to frame. What would be the easiest way to do that? – practicemakesperfect Apr 04 '16 at 18:57
1

There is not. Gif images can not "see" the mouse. They are merely images which display. In order to pause an animated gif it requires the swapping of a similar image which is not animated.

That being posted, there are jquery plug ins to animate a sprite consisting of static images. These plug ins would allow the sprites to pause on mouse over

Scott
  • 21,475
  • 8
  • 43
  • 55
  • 1
    Looking for alternative I discovered [GreenSock](http://www.greensock.com/get-started-js/) [Gratis and Open Source (though not free)] it may be worth a look. – Theraot Dec 17 '13 at 21:09
  • Ah thank you for this response. I will look more into the "jquery method" I haven't seen any plugins on this so this also helps. I will look into this and see if it does any good. – XavierTheGreat Dec 18 '13 at 06:44