Play Gif on Mouseover and Pause Gif on mouse out without replacing images?
Asked Answered
S

2

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/

Samples answered 17/12, 2013 at 20:38 Comment(11)
It is not using gif.It is using CSS3Dhobi
The tutorial you've linked is about CSS animation, not about GIF.Edmonson
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.Prittleprattle
I'd break your gif into separate frames and then use keyframes to animate it. Then you can stop wherever you want.Vincenz
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 achievePrittleprattle
Here is the codepen url which the site you refrenced to is providing: codepen.io/valhead/pen/91c4b0f93364fa25d7eca2c85140654bDhobi
"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.Fadeless
@Fadeless I bet that he is talking about other examples including actual .gifs, 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.Prittleprattle
@ZachL I think those are CSS animations, like the logo of davidwalsh.name.Fadeless
@Fadeless yes, as noted in several comments above, the linked demo uses CSS animations, not .gifs. 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.Prittleprattle
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.Samples
V
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

Vincenz answered 17/12, 2013 at 21:3 Comment(10)
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!Samples
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.Vincenz
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!Samples
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!Samples
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. #15469536 If it's not possible no worries, just an aesthetic request here! Thanks again!Samples
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).Vincenz
@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.Vincenz
Nailed it! Thanks so much for the "faux firefox fallback!" This will definitely become useful for those with iffy browsers. You're a lifesaver!Samples
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.Pavid
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?Autochthonous
P
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

Pavid answered 17/12, 2013 at 20:47 Comment(2)
Looking for alternative I discovered GreenSock [Gratis and Open Source (though not free)] it may be worth a look.Fadeless
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.Samples

© 2022 - 2024 — McMap. All rights reserved.