const Flickity = require("flickity"); /// La fonction vCarousel reçoit un tableau d'ids des conteneurs HTML des vidéos à afficher successivement. /// Le tableau n'est pas dédoublonné, pour rester libre d'afficher plusieurs fois la même vidéo durant un tour du carrousel. /// On peut éventuellement fournir l'id du conteneur de la première vidéo à afficher lors de l'appel /// Ou encore indiqué qu'aucune ne doit être affichée sans action en passant une chaîne vide /// Par défaut la première vidéo de la liste sera affichée export const vCarousel = (vContainers:string[], firstVideoId?:string) : void => { interface videoDOM { id: string; containerElt: HTMLElement; videoElt: HTMLMediaElement; } // On commence par vérifier que les ids de conteneurs fournis sont correctes. // C'est-à-dire qu'il s'agit bien d'éléments HTML contenant au moins une vidéo. const realVContainers : videoDOM[] = []; for(let containerId of vContainers) { let checkContainerExist=document.getElementById(containerId); if(checkContainerExist===null) console.error("Aucun élément HTML trouvé dans la page pour l'id fourni "+containerId); else { let checkVideoExist=document.querySelector("#"+containerId+" video"); if(checkVideoExist===null) console.error("Aucune balise vidéo trouvée dans l'élément HTML ayant comme id "+containerId); else realVContainers.push({id:containerId, containerElt:checkContainerExist, videoElt:checkVideoExist}); } } // Si firstVideoId a été fourni, on vérifie aussi qu'il est valide. if(firstVideoId!==undefined && firstVideoId!=="" && (realVContainers.findIndex(video => video.id === firstVideoId) === -1)) { console.error("Vous avez fourni l'id de la vidéo à afficher en premier ("+firstVideoId+"), mais il n'est pas valide."); firstVideoId=undefined; } // Il doit rester au moins deux vidéos à faire tourner. let nbVContainers=realVContainers.length; if(nbVContainers < 2) console.error("Il faut fournir au moins deux conteneurs valides pour faire tourner le carrousel."); else { // Tous les conteneurs sont cachés, sauf celui demandé. // La fin de lecture d'une vidéo provoque son remplacement par la suivante. for (let i = 0; i < nbVContainers; i++) { let vContainer=realVContainers[i].containerElt; let video=realVContainers[i].videoElt; if((firstVideoId!==undefined && realVContainers[i].id!==firstVideoId) || (firstVideoId===undefined && i!==0) || firstVideoId==="") vContainer.style.display = "none"; else vContainer.style.display = "block";// nécessaire dans le cas d'un réaffichage. video.addEventListener("ended", function() { vContainer.style.display = "none"; let nextVContainer: HTMLElement, nextHash: string; if(i < (nbVContainers-1)) { nextVContainer=realVContainers[i+1].containerElt; nextHash=realVContainers[i+1].id; } else { nextVContainer=realVContainers[0].containerElt; nextHash=realVContainers[0].id; } nextVContainer.style.display = "block"; // On adapte l'ancre de l'url de manière à ce qu'elle soit cohérente avec la vidéo affichée. // Attention car cela peut provoquer un déplacement dans la page la première fois pour atteindre l'ancre. window.location.assign("#"+nextHash); }); } } }