Search code examples
javascriptjqueryhtmlcssgsap

Cycle for animation made with GSAP


I have 3 pictures. They are changing with animation.

With GSAP I want to make the animation cycle which will repeat several times(5, 6 or 7 for example). I used the method .restart(), but it doest work correctly. I call this method after the third picture disappears, but then the cycle begins from the second picture and some animations doesn't work. So I dont know what to do. Please, help me :(

In simple terms, I have 3 pictures, which change with rotation, scale and opacity in order. After the third picture is fade out I want to repeat my animation similarly (with rotation, scale and opacity in order). So my problem is to make the cycle to do this.

HTML:

<div align="center">
    <img id ="image" src="http://s1.1zoom.me/b4445/4/Planets_Nebulae_in_space_518424_240x400.jpg" width="240px" height="400px">
    <img id ="image1" src="http://www.mobi-city.ru/wallpaper/image/nature_13_240x400.jpg" width="240px" height="400px">
    <img id ="image2" src="http://m.chromesphere.net/Finals/chromesphere/chromesphere_i900_240x400.jpg" width="240px" height="400px">
</div>

CSS:

#image, #image1, #image2 {
    display: none;
    position: relative;
    left: 0%;
}

div {
    width: 100%;
}

JS:

$("#image").css("display", "block");
var image = document.getElementById('image');
var image1 = document.getElementById('image1');
var image2 = document.getElementById('image2');

    var tl = new TimelineLite({
        delay: 2,
        onComplete: function() {
            $("#image").css("display", "none");
            $("#image1").css("display", "block");
            TweenLite.fromTo(image1, 1, {scale: 0, opacity: 0}, {scale: 1, opacity: 1, delay: 0})

                            var tl_1 = new TimelineLite({
                            delay: 2,
                            onComplete: function() {
                                $("#image1").css("display", "none");
                                $("#image2").css("display", "block");
                                TweenLite.fromTo(image2, 1, {scale: 0, opacity: 0}, {scale: 1, opacity: 1, delay: 0})

                                                var tl_2 = new TimelineLite({
                                                delay: 2,
                                                onComplete: function () {
                                                    alert("done");
                                                    tl.restart();
                                                }
                                                });

                                                tl_2.add(TweenLite.to(image2, 1, {scale: 0, opacity: 0, ease: Back.easeIn}), 1);
                                                tl_2.add(TweenLite.to(image2, 2, {x: 0, rotation: 360, ease: Power1.easeInOut}), 0);




                                }
                            });

                    tl_1.add(TweenLite.to(image1, 1, {scale: 0, opacity: 0, ease: Back.easeIn}), 1);
                    tl_1.add(TweenLite.to(image1, 2, {x: 0, rotation: 360, ease: Power1.easeInOut}), 0);

        }
    });

    tl.add(TweenLite.to(image, 1, {scale: 0, opacity: 0, ease: Back.easeIn}), 1);
    tl.add(TweenLite.to(image, 2, {x: 0, rotation: 360, ease: Power1.easeInOut}), 0);

CodePen:

https://codepen.io/syncmaxim/pen/ZMexPZ?editors=0010


Solution

  • It was very difficult for me to understand what you were trying to do but I'm pretty sure your code was far more complicated than it needed to be. I took a guess at the type of effect you were going for, and created this codepen: https://codepen.io/GreenSock/pen/LJxgBv?editors=0010

    var images = document.querySelectorAll("img"),
        delayTime = 2,
        animationTime = 1,
        tl = new TimelineMax({repeat:-1, delay:animationTime + delayTime, repeatDelay:delayTime});
    
    TweenMax.set(images, {autoAlpha:0, scale:0});
    //animate the first image in (don't put this in the timeline because it's different - there's no image showing behind it!)
    TweenMax.to(images[0], animationTime, {autoAlpha:1, scale:1});
    
    //now loop through the rest of the images and build their animations
    for (var i = 1; i < images.length; i++) {
      tl.to(images[i], animationTime, {autoAlpha:1, scale:1}, (i-1) * (animationTime + delayTime));
      //after the new image animates in, we can hide the old one that's behind it (aids browser performance)
      tl.set(images[i-1], {autoAlpha:0, scale:0});
    }
    
    //now take the FIRST image and change the zIndex so that it's ON TOP of the last image, and animate it in. 
    tl.fromTo(images[0], animationTime, {zIndex:100}, {autoAlpha:1, scale:1, delay:delayTime, immediateRender:false});
    

    Hopefully it's easy to tweak things to get what you need. I added comments to help explain what's going on.

    If you have GSAP-related questions, feel free to post them in the dedicated forums at https://greensock.com/forums. It'd be best if you could provide a sample codepen that demonstrates the issue - that makes troubleshooting much faster.

    Happy tweening!