metafizzy / flickity

:leaves: Touch, responsive, flickable carousels
https://flickity.metafizzy.co
7.53k stars 602 forks source link

Feature request: Add class/event what slide is currently dragged as selected #880

Closed jkosonen closed 4 years ago

jkosonen commented 5 years ago

Would be helpful to see what slide is currently being dragged, so that I could make some UI magic even when slide is only just dragged to isSelected place, but not yet released.

Now you get the selected slide only after you end your drag.

acemir commented 5 years ago

@jkosonen Maybe you could use dragStart and dragEnd events, for example:


flkty.on( 'dragStart', function( event, pointer ) {
   event.target.classList.add('dragging');
});
flkty.on( 'dragEnd', function( event, pointer ) {
   event.target.classList.remove('dragging');
});
jkosonen commented 5 years ago

@acemir I don't think that would work as I want. I would like to have the selected cell updated already when dragging. Your example would only trigger on start of the dragging and would not update it when dragging continues.

acemir commented 5 years ago

@jkosonen In this case, you could use the dragMove event that fires continuously while the slide is being dragged.

desandro commented 5 years ago

I would like to have the selected cell updated already when dragging. Your example would only trigger on start of the dragging and would not update it when dragging continues.

What you're asking for is a feature that calculates which slide is closest to its selected position, and sets a class accordingly.

Here's one way to do it! Using the scroll event and calculations with .slides.target. See demo https://codepen.io/desandro/pen/XoEpab

// external js: flickity.pkgd.js
var $carousel = $('.carousel').flickity({
});

var flkty = $carousel.data('flickity');

var scrollSlide = flkty.slides[0];

$carousel.on( 'scroll.flickity', function() {
  // calculate closest slide
  var distances = flkty.slides.map( function( slide, i ) {
    return Math.abs( -slide.target - flkty.x );
  });
  var minDistance = Math.min.apply( Math, distances );
  var minIndex = distances.indexOf( minDistance );
  var closestSlide = flkty.slides[ minIndex ];
  // change scrollSlide
  if ( closestSlide != scrollSlide ) {
    scrollSlide.cells.forEach( function( cell ) {
      cell.element.classList.remove('is-closest');
    });
    closestSlide.cells.forEach( function( cell ) {
      cell.element.classList.add('is-closest');
    });
    // update state variable
    scrollSlide = closestSlide;
  }
});
acemir commented 5 years ago

Nice! The scroll event really is a better option!! I made a little refactor to encapsulate in a reusable function: https://codepen.io/acemir/pen/PXRJzN

Julix91 commented 5 years ago

I like this a lot! But it doesn't work with wrapAround - and it would be really awesome together with that.

Julix91 commented 5 years ago

Acemir solved it!

https://codepen.io/acemir/pen/MRgNwJ