Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick animate when moving past the center

I am using slick to make a carousel like this:

enter image description here

I have used these settings:

{
    dots: false,
    slidesToShow: 3,
    focusOnSelect: true,
    swipeToSlide: true,
    centerMode: true,
    event: {
        init: scope.init
    }
}

This seems to get the actual animation working fine. The next part (which is the bit causing me issues) is trying to get the "dot" and text to animate in size an colour. Does anyone know how I might go about doing that? I am trying to use the swipe method but the issue is working out which is the item closest to the center as I am swiping.

Any help would be greatly appreciated.


Update

So I have managed to do part of this. I added the init callback to the options and added some code to work out the position of the center element and it's size.

// Extend our scope
angular.extend(scope, {
    init: function (e, slick) {

        // Get our dragable element
        var sizes = scope.options.sizes,
            draggableElement = element[0].getElementsByClassName('draggable')[0],
            centerElement = draggableElement.getElementsByClassName('slick-center')[0].childNodes[0];

        // Set the active dimensions and margins
        centerElement.style.width = sizes.finish + 'px';
        centerElement.style.height = sizes.finish + 'px';
        centerElement.style.borderRadius = sizes.finish / 2 + 'px';
        centerElement.style.marginTop = '0';
        centerElement.style.marginBottom = '0';

        slick.$list.on('touchmove.slick mousemove.slick', function () {
            _resizePoint(slick, this, sizes);
        });
    }
});

// Extend our options
angular.extend(scope.options, {
    event: {
        init: scope.init
    },
    sizes: {
        start: 18,
        finish: 50
    }
});


// Resizes the point
var _resizePoint = function (slick, container, sizes) {

    // Get our actual Width
    var containerPadding = parseInt(container.style.paddingLeft),
        containerWidth = container.offsetWidth - containerPadding * 2;

    // If we have a swipe left
    if (slick.swipeLeft) {

        // Get our slide index
        var center = containerWidth / 2,
            left = -slick.swipeLeft > 0 ? -slick.swipeLeft : slick.swipeLeft,
            distance = left + center,
            index = Math.floor(distance / slick.slideWidth);

        // Get the active element
        var activeElement = container.childNodes[0].childNodes[index].childNodes[0];

        // Get our start point
        var half = slick.slideWidth / 2,
            start = center - half,
            position = (index * slick.slideWidth) - left;

        // Get our dimensions 
        var startDimension = sizes.start,
            finishDimension = sizes.finish,
            startMargin = (finishDimension - startDimension) / 2

        // Get the percentage in relation to the center
        var percent = (center - position) / half,
            directionalPercent = position > start ? percent : 2 - percent,
            dimension = startMargin + ((finishDimension - startMargin) * directionalPercent),
            marginPercent = 1 - directionalPercent,
            margin = startMargin * marginPercent;

        // Apply our sizes to our element
        activeElement.style.width = dimension + 'px';
        activeElement.style.height = dimension + 'px';
        activeElement.style.borderRadius = dimension / 2 + 'px';
        activeElement.style.marginTop = margin + 'px';
        activeElement.style.marginBottom = margin + 'px';
    }
};

This works while dragging, but when focusOnSelect is true, click an item does not resize it. Also using the navigational arrows doesn't work and finally when you let go of drag, when it moves to the center, that doesn't resize either.

I was hoping to override the animateSlide method to insert my code, but my code works on the current items position and I don't think that will work with animateSlide.

I have added a bounty now, because I assume someone can help me with this.

Update 2

I have created a codepen to illustrate my issue.

http://codepen.io/r3plica/pen/vKPyxE?editors=1010

If you drag left or right, you can see that the "dot" increases and decreases in size. But if you click any of the dots it just moves straight there with not size change.

I hope that explains my issue :)

like image 874
r3plica Avatar asked Aug 08 '16 16:08

r3plica


2 Answers

You can take advantage of the CSS3 scale() transform to grow the size of the bubble to however big you want it like so (applying the style directly to the .slick-center class of course):

.slick-slide.slick-center .slider-point {
  -webkit-transform: scale( 2.5 );
     -moz-transform: scale( 2.5 );
       -o-transform: scale( 2.5 );
      -ms-transform: scale( 2.5 );
          transform: scale( 2.5 );
}

Demo: http://codepen.io/andresilich/pen/jAREmO

like image 95
Andres Ilich Avatar answered Nov 10 '22 11:11

Andres Ilich


Check this codepane demo

Here I have made changes in CSS file and JS file

In CSS file I have added CSS properties for animation and make bigger circle on current slide.

.slick-slider .slick-slide .slider-point
{
  transition:  1s ease-in;
}

And in JS file I have removed some of your code and added callback of slick sliders based on Event section in documentation

angular.module('slick', ['slickCarousel']).controller('MainController', function() {
    var self = this;
    self.items = [1, 2, 3, 4, 5];
}).directive('pkSlider', ['$timeout', function($timeout){
return {
    restrict: 'A',

    scope: {
        items: '=pkSlider',
        options: '='
    },

    templateUrl: 'assets/templates/pk-slider.html',

    link: function(scope, element){

        $timeout(function(){
            // Extend our options
            angular.extend(scope.options, {
                event: {
                // init: scope.init,
                init: function(event, slick){
                    // let's do this after we init the banner slider
                    sizes=slick.options.sizes;
                    var margin=(sizes.finish-sizes.start)/2;
                    $(slick.$slides[slick.initials.currentSlide]).find('.slider-point').css({
                        width: sizes.finish + 'px',
                        height: sizes.finish + 'px',
                        borderRadius: sizes.finish / 2 + 'px',
                        marginTop: '0',
                        marginBottom: '0'
                    });    
                },
                beforeChange: function(event, slick, currentSlide, nextSlide){

                    sizes=slick.options.sizes;

                    var margin=(sizes.finish-sizes.start)/2;

                    $(slick.$slides[currentSlide]).find('.slider-point').css({
                        width: sizes.start + 'px',
                        height: sizes.start + 'px',
                        borderRadius: sizes.start / 2 + 'px',
                        marginTop: margin+'px',
                        marginBottom: margin+'px'
                    });

                    $(slick.$slides[nextSlide]).find('.slider-point').css({
                        width: sizes.finish + 'px',
                        height: sizes.finish + 'px',
                        borderRadius: sizes.finish / 2 + 'px',
                        marginTop: '0',
                        marginBottom: '0'
                    })
                }
            },
            sizes: {
            start: 18,
            finish: 50
            }
        });
    });
}};
}]);
like image 34
Haresh Vidja Avatar answered Nov 10 '22 10:11

Haresh Vidja