1class GallerySlider { 2 constructor(sliderId, config) { 3 this.sliderId = sliderId; 4 this.config = window[`blb_image_gallery_${sliderId}`]; 5 this.sliderInstance = document.querySelector(`.blb-profile-gallery[slider-id="${sliderId}"]`); 6 this.container = this.sliderInstance.querySelector('.blb-profile-gallery-container'); 7 this.containerSection = this.sliderInstance.closest('.pin-section-container'); 8 if(this.containerSection == null) { 9 this.containerSection = this.sliderInstance; 10 } 11 this.items = Array.from(this.sliderInstance.querySelectorAll('.blb-profile-gallery-item')); 12 this.dots = this.sliderInstance.querySelector('.blb-profile-gallery-dots'); 13 this.arrows = this.sliderInstance.querySelectorAll('.blb-profile-gallery-arrow'); 14 this.items_before_overlap_size = 3; 15 this.items_after_overlap_size = 8; 16 this.item_width = "20rem"; 17 18 this.interval = null; 19 20 this.xStart = null; 21 this.yStart = null; 22 23 if(window.innerWidth > 976) { 24 this.scroll_behave = this.config.scroll_behave; 25 this.items_before_overlap_size = 3; 26 this.items_after_overlap_size = 8; 27 } 28 else { 29 this.scroll_behave = false; 30 this.items_before_overlap_size = 0; 31 this.items_after_overlap_size = 4; 32 this.sliderInstance.addEventListener('touchstart', (e) => this.handleTouchStart(e), false); 33 this.sliderInstance.addEventListener('touchmove', (e) => this.handleTouchMove(e), false); 34 } 35 36 if(this.scroll_behave) { 37 this.scene = null; 38 this.sceneDuration = (this.config.scene_duration) ? this.config.scene_duration : 3000; 39 this.sceneLockProgress = false; 40 } 41 else if(!this.scroll_behave && this.config.autoplay) { 42 this.createInterval(); 43 this.sliderInstance.addEventListener('mouseover', this.deleteInterval.bind(this)); 44 this.sliderInstance.addEventListener('mouseout', this.createInterval.bind(this)); 45 } 46 47 this.init(); 48 49 } 50 51 init() { 52 this.setContainerWidth(); 53 this.setupDots(); 54 this.bindArrows(); 55 this.bindIndexControls(this.items, "item"); 56 this.bindIndexControls(Array.from(this.dots.children), "dot"); 57 if(window.innerWidth > 767) 58 this.bindIndexControls(Array.from(this.sliderInstance.querySelectorAll('.blb-profile-gallery-tab')), "tab"); 59 else 60 { 61 this.sliderInstance.querySelector(".blb-profile-gallery-tabs-container").addEventListener('click', (e) => { 62 this.sliderInstance.querySelector(".blb-profile-gallery-tabs-container").classList.toggle("open"); 63 }); 64 this.bindIndexControls(Array.from(this.sliderInstance.querySelectorAll('.blb-profile-gallery-tab')), "tab"); 65 } 66 67 this.setHeight(); 68 this.setItemWidth(); 69 70 this.createObserver(); 71 this.gotoIndex(0, true); 72 73 if(this.scroll_behave) { 74 this.setupScrollMagic(); 75 this.scene.on("progress", this.scrollProgress.bind(this)); 76 } 77 window.addEventListener("resize", this.handleResize.bind(this)); 78 79 } 80 81 setContainerWidth() { 82 this.container.style.width = `${(this.items.length * 15) + 60}vw`; 83 this.container.setAttribute('data-index', 0); 84 } 85 86 setupDots() { 87 this.items.forEach((item, i) => { 88 const dot = document.createElement('div'); 89 dot.classList.add('blb-profile-gallery-dot'); 90 dot.setAttribute('data-index', i); 91 dot.innerHTML = '<span></span>'; 92 if (i === 0) dot.classList.add('active'); 93 this.dots.appendChild(dot); 94 }); 95 } 96 97 gotoIndex(newIndex, isScroll = false) { 98 99 if(newIndex < 0 || newIndex == null || newIndex == undefined) {newIndex = 0;} 100 if(newIndex > this.items.length-1) {newIndex = this.items.length-1;} 101 102 let oldIndex = parseInt(this.container.getAttribute('data-index')); 103 this.container.setAttribute('data-index', newIndex); 104 105 this.sliderInstance.querySelector(`.blb-profile-gallery-dot[data-index='${oldIndex}']`).classList.remove('active'); 106 this.sliderInstance.querySelector(`.blb-profile-gallery-dot[data-index='${newIndex}']`).classList.add('active'); 107 108 this.sliderInstance.querySelector(`.blb-profile-gallery-tab[data-index='${oldIndex}']`).classList.remove('active'); 109 this.sliderInstance.querySelector(`.blb-profile-gallery-tab[data-index='${newIndex}']`).classList.add('active'); 110 111 // Loop through and update items
112 this.items.forEach((item, i) => { 113 item.classList.remove('active'); 114 if (i === newIndex) item.classList.add('active'); 115 116 let translateValue = "0rem"; 117 if (i <= newIndex) { 118 translateValue = `calc(${i * this.items_before_overlap_size}rem)`; 119 } 120 if (i > newIndex) { 121 translateValue = `calc(${(i - (newIndex + 1)) * this.items_after_overlap_size}rem + ${this.item_width} + ${newIndex * this.items_before_overlap_size}rem)`; 122 } 123 item.style.transform = `translateX(${translateValue})`; 124 }); 125 126 if(this.scroll_behave && !isScroll) { 127 this.sceneLockProgress = true; 128 129 this.scene.off("enter"); 130 let percent_value = Math.round((newIndex + 0.25) / this.items.length * 100); 131 let scroll_value = this.scene.scrollOffset() + (percent_value * this.sceneDuration/100); 132 133 window.scrollTo({ 134 top: scroll_value, 135 behavior: "smooth" // smooth scrolling 136 }); 137 138 let that = this; 139 setTimeout(() => { 140 that.sceneLockProgress = false; 141 },600); 142 } 143 if(this.config.autoplay) { 144 clearInterval(this.interval); 145 this.createInterval(); 146 } 147 148 } 149 150 bindArrows() { 151 this.arrows.forEach((arrow) => { 152 arrow.addEventListener('click', (e) => { 153 let target = e.target; 154 while (target != null && target.getAttribute("data-offset") === null) { 155 target = target.parentElement; 156 } 157 if (target === null) return; 158 159 let offset = parseInt(target.getAttribute("data-offset")); 160 let index = parseInt(this.container.getAttribute('data-index')); 161 let newIndex = index + offset; 162 this.gotoIndex(newIndex); 163 }); 164 }); 165 } 166 167 168 bindIndexControls(items, type) { 169 items.forEach((item, i) => { 170 item.addEventListener('click', (e) => { 171 this.gotoIndex(i); 172 }); 173 }); 174 } 175 176 setupScrollMagic() { 177 let offset = this.getOffset(); 178 console.log("offset", offset); 179 this.scene = new ScrollMagic.Scene({ 180 triggerElement: this.containerSection, // l'élément qui déclenche l'événement 181 triggerHook: 0, // le point de déclenchement (0-1) 182 offset: offset, // décalage en pixels 183 duration: this.sceneDuration // durée en pixels 184 }) 185 186 this.scene.setPin(this.containerSection); 187 188 this.scene.addTo(window.scrollmagic_controller) 189 .on("enter", function (e) { 190 console.log("Le slider est centré"); 191 }); 192 } 193 194 scrollProgress(event) { 195 var scrollPercentage = event.progress * 100; 196 if(!this.sceneLockProgress) { 197 this.gotoIndex(Math.round((this.items.length) * (scrollPercentage / 100)), true); 198 } 199 } 200 201 getOffset() { 202 const containerRect = this.containerSection.getBoundingClientRect(); 203 const sliderRect = this.sliderInstance.getBoundingClientRect(); 204 const sliderFromTop = (containerRect.height - sliderRect.height) / 2; 205 const spaceTop = (window.innerHeight - sliderRect.height) / 2; 206 console.log("containerRect.height, sliderRect.height, sliderFromTop, spaceTop, offset", containerRect.height, sliderRect.height, sliderFromTop, spaceTop, sliderFromTop - spaceTop); 207 return sliderFromTop - spaceTop; 208 } 209 210 setHeight() { 211 this.container.style.height = "auto"; 212 var max_height = 0; 213 this.items.forEach((item) => { 214 item.style.height = "auto"; 215 let item_rect = item.getBoundingClientRect(); 216 if(item_rect.height > max_height) { 217 max_height = item_rect.height; 218 } 219 }); 220 this.items.forEach((item) => { 221 item.style.height = max_height + "px"; 222 }); 223 this.container.style.height = max_height + "px"; 224 } 225 226 setItemWidth() 227 { 228 if(window.innerWidth < 976) { 229 this.item_width = ((this.sliderInstance.getBoundingClientRect().width > 500) ? 500 : this.sliderInstance.getBoundingClientRect().width) + "px";
230 this.items.forEach((item) => { 231 item.style.maxWidth = this.item_width; 232 }); 233 } 234 else { 235 this.items.forEach((item) => { 236 item.style.maxWidth = "none"; 237 }); 238 } 239 240 } 241 242 handleResize() 243 { 244 if(window.innerWidth < 976) { 245 this.scroll_behave = false; 246 if(this.scene) 247 { 248 this.scene.off("progress", this.scrollProgress.bind(this)); 249 this.scene.destroy(true); 250 this.scene = null; 251 } 252 this.items_before_overlap_size = 0; 253 this.items_after_overlap_size = 4; 254 } 255 else { 256 this.scroll_behave = this.config.scroll_behave; 257 this.items_before_overlap_size = 3; 258 this.items_after_overlap_size = 8; 259 } 260 this.setHeight(); 261 this.setItemWidth(); 262 if(this.scroll_behave) { 263 let offset = this.getOffset(); 264 console.log("offset", offset); 265 this.scene.offset(offset); 266 this.scene.refresh(); 267 } 268 } 269 270 createObserver() { 271 let observer = new IntersectionObserver((entries, observer) => { 272 entries.forEach(entry => { 273 if (entry.isIntersecting) { 274 //createInterval(); 275 observer.unobserve(entry.target); 276 } 277 }); 278 }, {}); 279 280 observer.observe(this.sliderInstance); 281 this.sliderInstance.classList.add("slider-loaded"); 282 } 283 284 createInterval() 285 { 286 clearInterval(this.interval); 287 this.interval = setInterval(() => { 288 let currentIndex = parseInt(this.container.getAttribute('data-index')); 289 let nextIndex = (currentIndex + 1) % this.items.length; 290 this.gotoIndex(nextIndex); 291 }, this.config.time_by_slide); 292 } 293 294 deleteInterval() { 295 clearInterval(this.interval); 296 } 297 298 299 handleTouchStart(e) { 300 const firstTouch = e.touches[0]; 301 this.xStart = firstTouch.clientX; 302 this.yStart = firstTouch.clientY; 303 } 304 305 handleTouchMove(e) { 306 if (!this.xStart || !this.yStart) { 307 return; 308 } 309 310 let xEnd = e.touches[0].clientX; 311 let yEnd = e.touches[0].clientY; 312 313 let xDiff = this.xStart - xEnd; 314 let yDiff = this.yStart - yEnd; 315 316 if (Math.abs(xDiff) > Math.abs(yDiff)) { 317 if (xDiff > 0) { 318 /* Swipe gauche */ 319 this.gotoNext(); 320 } else { 321 /* Swipe droit */ 322 this.gotoPrev(); 323 } 324 } 325 // Réinitialiser les valeurs 326 this.xStart = null; 327 this.yStart = null; 328 } 329 330 gotoNext() { 331 let index = parseInt(this.container.getAttribute('data-index')); 332 let newIndex = index + 1; 333 this.gotoIndex(newIndex); 334 } 335 336 gotoPrev() { 337 let index = parseInt(this.container.getAttribute('data-index')); 338 let newIndex = index - 1; 339 this.gotoIndex(newIndex); 340 } 341 342 343} 344 345window.addEventListener('load', (event) => { 346 var gallerySliders = document.querySelectorAll(".blb-profile-gallery"); 347 gallerySliders.forEach((slider) => { 348 let config = window[`blb_image_gallery_${slider.getAttribute("slider-id")}`]; 349 new GallerySlider(slider.getAttribute("slider-id"), config); 350 }); 351}); 352
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.