PageSourceSearch

https://biologbook.fr/wp-content/themes/biologbook/blocks/blb-profile-gallery/blb-profile-gallery.js?ver=6.3.6

js biologbook.fr collected 2026-10-07 08:17:25 UTC 12,474 bytes, 352 lines download raw bytes

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.