Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
drNo77

Stop two timelines repeating after first loop in slider carousel

Recommended Posts

Hi, I'm using a custom slider carousel template to build a mobile banner for this ad platform, which is mostly built in jQuery and JavaScript, and I'm trying to make the tweens on frames 2 and 3 (timeline variables are called f2Timeline and f3BorderTimeline) animate the first time the slider plays on screen, but then keep them static and prevent them from repeating as the slider loops.

 

I think I'm nearly there, but the tweens animate continuously. What I've done so far is I've called a function called "checkFrame()" that animates the tweens according to the frame number, and then have the function declared inside the last conditional statement of the "goSlide" function . I think I might have to write another conditional statement to determine what should happen when the variable "slideCount" is triggered more than once, but I've tried it,  and I still can't work it out.

 

/**
 * Customise product click throughs here
 */
var STANDARD_BANNER_URL = "https://playground.xyz";
var SUPER_SKIN_HERO_URL = 'https://playground.xyz';

/************************** DO NOT EDIT BELOW **************************/
var superSkin = new xyz.superSkin({
  version: 2
});
var docs = superSkin.docs;

var bannerClickUrl = xyzContext.tokens.bannerClick || STANDARD_BANNER_URL;
var heroClickUrl = xyzContext.tokens.heroClick || SUPER_SKIN_HERO_URL;

// Slider vars
var TRANSITION_SPEED = 400;
var AUTO_SLIDE_INTERVAL= 3500;
var f2Timeline = new TimelineMax();
var f3Timeline = new TimelineMax();
//var f3Timeline = new TimelineMax();

/************************** DO NOT EDIT ABOVE **************************/


superSkin.on("banner", function() {
  superSkin.clickArea($('body', docs.banner), bannerClickUrl, "Banner click");
});

superSkin.on('launch', function() {

  /** ** SLIDER SCRIPT  ****/

  // DEPENDENCY on the presence of correct class names on slider elements in html, see Selector below

  // 1. Basic object for our stuff
  var slider = window.slider = {};

  // 2. Settings
  slider.sliderPanelSelector = '.slider-panel';
  slider.sliderPaginationSelector = '.slider-pagination';
  slider.sensitivity = 25; // horizontal % needed to trigger swipe

  // 2. Placeholder to remember which slide we’re on
  slider.activeSlide = 0;

  // 3. Slide counter
  slider.slideCount = 0;

  // 4. Initialization + event listener
  slider.init = function(selector) {
    // 4a. Find the container
    slider.sliderEl = superSkin.docs.hero.querySelector(selector);

    // 4b. Count stuff
    slider.slideCount = slider.sliderEl.querySelectorAll(slider.sliderPanelSelector).length;

    console.log('slideCount', slider.slideCount);

    $('#slider', docs.hero).css('width', (slider.slideCount * 100) + '%');

    // 4c. Populate pagination
    var n = 0;
    for (n; n < slider.slideCount; n++) {
      var activeStatus = n == slider.activeSlide ? ' class="is-active"' : '';
      slider.sliderEl.parentElement.querySelector(slider.sliderPaginationSelector).innerHTML += '<div ' + activeStatus + '></div>';
    }

    // 4d. Set up HammerJS
    var sliderManager = new Hammer.Manager(slider.sliderEl);
    sliderManager.add(new Hammer.Pan({
      threshold: 0,
      pointers: 0
    }));
    sliderManager.on('pan', function(e) {
      // 4e. Calculate pixel movements into 1:1 screen percents so gestures track with motion
      var percentage = 100 / slider.slideCount * e.deltaX / window.innerWidth;

      // 4f. Multiply percent by # of slide we’re on
      var percentageCalculated = percentage - 100 / slider.slideCount * slider.activeSlide;

      // 4g. Apply transformation
      slider.sliderEl.style.transform = 'translateX( ' + percentageCalculated + '% )';

      // 4h. Snap to slide when done
      if (e.isFinal) {

        // Log an engagement
        superSkin.tracking.engagement('hero', {
          event: {
            label: 'Swipe'
          }
        });

        if (e.velocityX > 1) {
          slider.goTo(slider.activeSlide - 1);
        } else if (e.velocityX < -1) {
          slider.goTo(slider.activeSlide + 1);
        } else {
          if (percentage <= -(slider.sensitivity / slider.slideCount))
            slider.goTo(slider.activeSlide + 1);
          else if (percentage >= (slider.sensitivity / slider.slideCount))
            slider.goTo(slider.activeSlide - 1);
          else
            slider.goTo(slider.activeSlide);
        }
      }
    });
  };


  // 5. Update current slide
  slider.goTo = function(number) {
    // 5a. Stop it from doing weird things like moving to slides that don’t exist
    if (number < 0)
      slider.activeSlide = 0;
    else if (number > slider.slideCount - 1)
      slider.activeSlide = slider.slideCount - 1;
    else
      slider.activeSlide = number;
    
//     if (number > 0)
//        f2Timeline.stop(); 
    // 5b. Apply transformation & smoothly animate via .is-animating CSS
    var percentage = -(100 / slider.slideCount) * slider.activeSlide;

    $(slider.sliderEl).transition({x: percentage + '%'}, TRANSITION_SPEED);

    // 5c. Update the counters
    var pagination = slider.sliderEl.parentElement.querySelectorAll(slider.sliderPaginationSelector + ' > *');
    var slides = slider.sliderEl.parentElement.querySelectorAll(slider.sliderPanelSelector);
    var n = 0;
    for (n; n < pagination.length; n++) {
      var className = n == slider.activeSlide ? 'is-active' : '';
      var slideClass = n == slider.activeSlide ? 'slider-panel is-active' : 'slider-panel';
      pagination[n].className = className;
      slides[n].className = slideClass;
    }
  };

    slider.init('#slider');

  var autoplay = setInterval(goSlide, AUTO_SLIDE_INTERVAL);

  function goSlide() {
    if (slider.activeSlide === slider.slideCount - 1) {
      slider.goTo(0);
    } else {
      slider.goTo(slider.activeSlide + 1);
      checkFrame();
      console.log('test everything');
    } 
  }
  
  function checkFrame() {
    // if (slider.slideCount > 0) {
    if (slider.activeSlide === 1 && slider.slideCount > 1) {
      f2Timeline.add(new TweenMax.fromTo(roundel, 0.3, {scale:0}, {scale:1, ease:Back.easeOut, delay:0.5}));
      f2Timeline.add(new TweenMax.fromTo(roundelCopy1, 0.3, {scale:0}, {scale:1, ease:Back.easeOut}));
      f2Timeline.add(new TweenMax.fromTo(roundelCopy2, 0.3, {scale:0}, {scale:1, ease:Back.easeOut}));
      console.log('frame 2');
    } else if (slider.activeSlide === 2 && slider.slideCount > 1) {
      f3Timeline.add(new TweenMax.fromTo(topF2, 0.3, {scaleX:0}, {scaleX:1, ease:Power2.easeOut, delay:0.5}));
      f3Timeline.add(new TweenMax.fromTo(vertBorder, 0.2, {scaleY:0}, {scaleY:1, ease:Power2.easeOut}));
      f3Timeline.add(new TweenMax.fromTo(horizBorder, 0.2, {scaleX:0}, {scaleX:1, ease:Power2.easeOut}));
      f3Timeline.add(new TweenMax.fromTo(insetBox, 0.3, {y:-100}, {y:0, ease:Power2.easeOut}));
      f3Timeline.add(new TweenMax.fromTo(copy3, 0.3, {y:-100}, {y:0, ease:Power2.easeOut}));
      console.log('frame 3');
    }
}    
  
  function turnOffAnimation() {
    f2Timeline.stop();
  }
  
  $('.slider', docs.hero).on('touchstart', function(){
    clearInterval(autoplay);
  });

/** ** END SLIDER SCRIPT  ****/

  //HERO CLICK AREA
  superSkin.clickArea($('body', docs.hero), heroClickUrl, 'Hero click');
  

Any ideas? Cheers.

Link to comment
Share on other sites

Hey drNo77. You've got a lot of code there. It's pretty hard for us to debug without a minimal demo. I recommend that you create a minimal demo with all the parts unrelated to your question stripped out if you'd like help debugging. Otherwise you might not get a helpful reply.

 

Side notes:

  • We highly recommend using the GSAP 3 formatting so you can make use of some of GSAP's features like defaults. Learn more about that here:
  • You're making one of the most common GSAP mistakes: adding to a timeline that's already completed. What you should be doing instead is either setting your animation up beforehand and just using control methods (recommended) or new tweens/timelines depending on your setup. More about that in my article about animating efficiently.

 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×