How to animate and change a slider counter position in a clean way?
Asked Answered
P

2

7

I have a Swiper slider and a counter position like "1/10". I would like to change that current slide number (the 1) with an animation. I know how to replace the number but with this animation, it's like another story:

As you can see on the gif, it's working nicely if I click moderately on my slider, but when I double-triple-or-crazy click on the next link, that totally breaks the counter, due to the clone made in this gif example.
Do you know how can I do that in a better way?

I made a jsfiddle, working for the first count change only:
http://jsfiddle.net/asb39sff/1/

// Init
var $c_cur = $("#count_cur"),
    $c_next = $("#count_next");

TweenLite.set($c_next, {y: 12, opacity: 0}, "count");


// Change counter function
function photos_change(swiper) {
    var index = swiper.activeIndex +1,
        $current = $(".photo-slide").eq(index),
        dur = 0.8,
        tl = new TimelineLite();

    // Just a test
    tl.to($c_cur, dur, {y: -12, opacity: 0}, "count")
      .to($c_next, dur, {y: 0, opacity: 1}, "count")

    //$c_cur.text(index);
    //$c_next.text(index + 1);
}
Pace answered 26/4, 2015 at 0:2 Comment(1)
Given that your issue is when you have the animation, you might want to link to a fiddle with the animation.Impermissible
I
4

While I agree with @Tom Sarduy approach and actually would recommend it since it is a one-time creation of HTML elements but just to provide you with another idea, here is what I have been able to create quickly.

CSS changes:

.counter .next, .counter .count {
    position:absolute;
}
.counter .next {
    transform:translateY(-12px);
    left:0;
}

JavaScript changes:

//added before your [photos_change] method
var counter = $('.counter');
var currentCount = $('<span class="count">1<span/>');
counter.append(currentCount);
//

//and then inside your [photos_change] event handler
var prevCount = $('.count');
currentCount = $('<span class="count next">' + index + '<span/>');
counter.append(currentCount);
TweenMax.to(prevCount, dur, {
    y: -12,
    opacity: 0,
    onCompleteParams: [prevCount],
    onComplete: function (prevCount) {
        prevCount.remove();
    },
    ease: Power2.easeOut
});
TweenMax.fromTo(currentCount, dur, {
    y: 12,
    opacity: 0
}, {
    y: 0,
    opacity: 1,
    ease: Power2.easeOut
});
//

So I guess it is up to you to take whichever approach you like i.e. one-time creation of HTML elements on load or on click like the one I am proposing.

Apologies for the ugliness of the code, just something I cooked up in a hurry. Hope it helps in some way though.

Infirmary answered 26/4, 2015 at 12:13 Comment(3)
Thank you so much Tahir! Works like a charm without any lag or anything else. I just reworked the code to be easier and to also adapt it to my slide title.Pace
Glad it helped. While I am at it, animating x and y instead of top and left produces buttery smooth motion because ... Paul Irish said so :)Infirmary
Yeah sure, I'm now using translates over TRBL, that was an old test.Pace
L
0

I think your HTML structure is not good enough for the animation, so I created my own fiddle with another approach and custom html tags, the animation is done using CSS3 transitions and the numbers are precalculated to avoid fast clicking problems:

Jquery:

$('#change-button').click(function(){

    //Getting current slide
    var $current = $('.current'); 

    //Remove the class to find next one
    $current.removeClass('current');

    if($current.is(':last-child')){
        //Resetting the counter if is the last child
        $('#counter ul li:first').addClass('current');
        $('#counter ul').css('top','0px');
    }
    else{
        $current = $current.next();
        $current.addClass('current');
        //Getting the next number to recalculate 
        //the new top position
        var $num = parseInt($current.text());
        $('#counter ul').css('top',-($num-1)*18+'px');
    }

});

$('#change-button').click(function(){
    var $current = $('.current');
    $current.removeClass('current');
    
    if($current.is(':last-child')){
        //Resetting the counter
        $('#counter ul li:first').addClass('current');
        $('#counter ul').css('top','0px');
    }
    else{
        $current = $current.next();
        $current.addClass('current');
        var $num = parseInt($current.text());
        $('#counter ul').css('top',-($num-1)*18+'px');
    }
    
});
.container{
    background-color: #000;
    padding: 10px;
    color: #fff;
    width: 300px;
    float: left;
}
.container li{
    display: inline-block;
    vertical-align: middle;
}

#counter{
  width: 16px;
  height: 18px;
  overflow: hidden;
  position: relative;
}

#counter ul{
  position: absolute;
  padding: 0;
  margin: 0;
  height: 18px;
  width: 16px;
  transition: all .5s;
}

#counter ul li{
    display: block;
    clear: both;
    text-align: right;
}

#change-button{
    margin: 10px;
    float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <li>Graphics</li> 
    <li id="counter">
        <ul>
            <li class="current">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
            <li>6</li>
            <li>7</li>
            <li>8</li>
            <li>9</li>
            <li>10</li>
            <li>11</li>
            <li>12</li>
        </ul>
    </li>
    <li>/ 4</li>
</div>

<button id="change-button" href="#">Change!</button>

If the animation works for you you will have to integrate it with your code by generating the unordered list with all the values, knowing how many slides you have (should be easy).

Lien answered 26/4, 2015 at 5:43 Comment(2)
Thank you for your example Tom! Actually it works well, but it's kind constraining in my example to list allll items number in the html. Sometimes, I can have more than 20 items in my slider, that's why I thought about a solution based on a clone to prepare the next slide number.Pace
@flks: 20+ items is not an issue in HTML, consider cloning when you have more than 100 elements or so, and in that case you will also need ajax in your slider ;)Lien

© 2022 - 2024 — McMap. All rights reserved.