CanalPlay carrousels 

Encore un carrousel ?

slick

angular-carousel

slidesjs

unslider

Contraintes

  • Performance (+20 sliders par page),
  • Configurable,
  • Responsive (nombre d'items variables),
  • Mode infini,
  • Différentes tailles de vignettes,
  • Support touchscreens,
  • Autonome (objectif open-source),
  • Utilisation de thèmes pour les items.

Intégration de slick

Avantages

  • Ultra-configurable
  • Facile à mettre en place

 

Inconvénients

  • Performance très mauvaise,
  • Re-layout en permanence.

Solution non retenue

=> Responsive géré en js = Tailles des vignnettes calculée en px

Quelques carrousels

Solutions

Utiliser une configuration SASS/CSS

pour la gestion du responsive

Utiliser les translate3d pour déplacer les éléments (utilisation du GPU)

Utiliser React pour profiter du virtual DOM et réduire au maximum les re-layouts

Stack

  • HTML5
  • CSS3
  • Javascript (ES2015)
  • SASS
  • ReactJS
  • Gulp
  • Browserify
  • Babel
  • Mocha (unit tests framework)
  • Sinon (spies, stubs and mocks for the tests)

Une configuration SASS

$carousel: (
  ratios:(
    "16_9":(
      tablet:(
        breakpoint: 1285px,
        numberItem: 3,
        aspectRatio: 16 9
      ),
      desktop:(
        breakpoint: 1600px,
        numberItem: 4,
        aspectRatio: 16 9
      )
    ),
    "3_4":(
      tablet:(
        breakpoint: 1190px,
        numberItem: 5,
        aspectRatio: 3 4
      ),
      desktop:(
        breakpoint: 1681px,
        numberItem: 7,
        aspectRatio: 3 4
      )
    )
  )
) !default;

Utilisation des pourcentages

width: 25%

width: 25%

overflow-x: visible

  • Clic page 2 : transform: translate3d(-100%, 0px, 0px);
  • Clic page 3 : transform: translate3d(-200%, 0px, 0px);
  • Clic page 4 : transform: translate3d(-300%, 0px, 0px);

Aucun calcul JS à ce niveau

Seule opération JS

Récupérer la dernière page

window.getComputedStyle(node, ':before');
@each $ratio in map-keys(map-get($carousel, ratios)) {
  .dedcarousel--ratio#{$ratio} {
    &:before {
      content: "#{map-deep-get($carousel, ratios, $ratio, wide, numberItem)}";
    }
  }
}

Niveau SASS

Niveau JS

Utilisation de méthodes statiques

Eviter de multiplier les listeners


class Carousel extends React.Component {

/* Each caroussel instance calls it */
static addInstance(carousel) {
  if(!Carousel._instances.length) {
    window.addEventListener('resize', Carousel.onViewportChange);
    window.addEventListener('orientationchange', Carousel.onViewportChange);
  }
  Carousel._instances.push(carousel);
}

/* Called only once (even if several instances) */
static onViewportChange(e) {
  Carousel._instances.forEach(function(instance) {
    if(instance.onViewportChange) instance.onViewportChange();
  });
}

/* For each carousel */
onViewportChange() {
  // operations here
}

}

Carousel._instances = [];

CanalPlay

By Julien Herpin

CanalPlay

  • 729