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
- 717