PageSourceSearch

https://artbrussels.com/wp-content/themes/aaab/assets/js/vimeo-custom-player.js?ver=1791062630

js artbrussels.com collected 2026-10-03 21:26:05 UTC 9,631 bytes, 249 lines download raw bytes

1/**
2 * Custom Vimeo Player Implementation with lazy loading and anchor navigation
3 */
4(function() {
5    // Wait for DOM to be fully loaded
6    document.addEventListener('DOMContentLoaded', function() {
7        // Load Vimeo Player API
8        const tag = document.createElement('script');
9        tag.src = "https://player.vimeo.com/api/player.js";
10        const firstScriptTag = document.getElementsByTagName('script')[0];
11        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
12
13        // Wait for Vimeo API to load
14        tag.onload = function() {
15            setTimeout(function() {
16                initCustomPlayers();
17                // Handle initial hash if present
18                handleHashNavigation();
19            }, 100);
20        };
21    });
22
23    // Global variables
24    let currentlyPlaying = null;
25    let players = {};
26    let initialized = false;
27    let observerInitialized = false;
28
29    // Create intersection observer for lazy loading
30    const observerOptions = {
31        root: null,
32        rootMargin: '50px',
33        threshold: 0.1
34    };
35
36    let observer = new IntersectionObserver((entries) => {
37        entries.forEach(entry => {
38            if (entry.isIntersecting) {
39                const container = entry.target;
40                initializePlayer(container);
41                // Stop observing after initialization
42                observer.unobserve(container);
43            }
44        });
45    }, observerOptions);
46
47    function handleHashNavigation() {
48        if (window.location.hash) {
49            console.log('hash', window.location.hash);
50            const targetId = window.location.hash.substring(1);
51            const targetElement = document.getElementById(targetId);
52            
53            if (targetElement) {
54                // Find the closest video container
55                const videoContainer = targetElement.closest('.custom-vimeo-player');
56                
57                if (videoContainer) {
58                    // Ensure smooth scroll
59                    targetElement.scrollIntoView({ behavior: 'smooth' });
60                    // Initialize the target video if not already initialized
61                    initializePlayer(videoContainer);
62                } else {
63                    // Element exists but is not inside a video container
64                    console.warn('Target element is not inside a video container:', targetId);
65                    // Still scroll to the element
66                    targetElement.scrollIntoView({ behavior: 'smooth' });
67                }
68            } else {
69                console.warn('Target element not found:', targetId);
70            }
71        }
72    }
73
74    // Listen for hash changes
75    window.addEventListener('hashchange', handleHashNavigation);
76
77    function initCustomPlayers() {
78        if (initialized) return;
79        initialized = true;
80        
81        const playerContainers = document.querySelectorAll('.custom-vimeo-player');
82        
83        playerContainers.forEach((container) => {
84            // Start observing each container
85            observer.observe(container);
86        });
87    }
88
89    function initializePlayer(container) {
90        if (container.dataset.initialized === 'true') return;
91        container.dataset.initialized = 'true';
92
93        const iframe = container.querySelector('iframe');
94        const overlay = container.querySelector('.video-overlay');
95        const videoWrapper = container.querySelector('.video-embed-wrapper');
96        
97        if (!iframe) return;
98        
99        // Validate Vimeo URL
100        let src = iframe.getAttribute('src');
101        if (!src || !src.includes('vimeo.com')) {
102            console.warn('Invalid or missing Vimeo URL:', src);
103            return;
104        }
105        
106        // Force additional parameters in src URL
107        if (src.indexOf('?') === -1) {
108            src += '?';
109        } else {
110            src += '&';
111        }
112        
113        src = src.replace('background=1', '');
114        src += 'autoplay=0&controls=0&title=0&byline=0&portrait=0&transparent=1&dnt=1&autopause=0&pip=0&sidedock=0';
115        iframe.setAttribute('src', src);
116        
117        iframe.classList.add('vimeo-embed');
118        
119        const playerId = 'vimeo-player-' + Math.random().toString(36).substr(2, 9);
120        container.setAttribute('data-player-id', playerId);
121        
122        try {
123            const player = new Vimeo.Player(iframe, {
124                autoplay: false,
125                controls: false,
126                title: false,
127                byline: false,
128                portrait: false,
129                transparent: true,
130                dnt: true,
131                autopause: false,
132                pip: false
133            });
134            
135            players[playerId] = player;
136            
137            // Ensure video is paused on initialization
138            player.ready().then(function() {
139                player.pause();
140            }).catch(function(error) {
141                console.error('Player ready error:', error);
142            });
143            
144            // Create a click catcher for playing state
145            const clickCatcher = document.createElement('div');
146            clickCatcher.className = 'video-click-catcher';
147            videoWrapper.appendChild(clickCatcher);
148            
149            // Handle click on click catcher (when video is playing)
150            clickCatcher.addEventListener('click', function() {
151                if (currentlyPlaying === playerId) {
152                    player.pause();
153                    overlay.classList.remove('hidden');
154                    clickCatcher.classList.remove('active');
155                    currentlyPlaying = null;
156                }
157            });
158            
159            // Handle click on overlay/play button
160            overlay.addEventListener('click', function() {
161                if (currentlyPlaying && currentlyPlaying !== playerId) {
162                    // Pause any other playing video
163                    pauseAllOtherVideos(playerId);
164                }
165                
166                player.getPaused().then(function(paused) {
167                    if (paused) {
168                        player.play();
169                        overlay.classList.add('hidden');
170                        clickCatcher.classList.add('active');
171                        currentlyPlaying = playerId;
172                    } else {
173                        player.pause();
174                        overlay.classList.remove('hidden');
175                        clickCatcher.classList.remove('active');
176                        currentlyPlaying = null;
177                    }
178                }).catch(function(error) {
179                    console.error('Get paused error:', error);
180                });
181            });
182            
183            // Show overlay when video ends
184            player.on('ended', function() {
185                overlay.classList.remove('hidden');
186                clickCatcher.classList.remove('active');
187                currentlyPlaying = null;
188            });
189            
190            // Show overlay when video is paused
191            player.on('pause', function() {
192                overlay.classList.remove('hidden');
193                clickCatcher.classList.remove('active');
194            });
195            
196            // Force hiding any UI elements after player initialization
197            player.ready().then(function() {
198                // Direct control over the iframe content
199                setTimeout(function() {
200                    try {
201                        // Try to post a message to the iframe to hide controls
202                        iframe.contentWindow.postMessage(JSON.stringify({
203                            method: 'setVolume',
204                            value: 1
205                        }), '*');
206                        
207                        // Apply CSS overrides to hide controls
208                        const styleTag = document.createElement('style');
209                        styleTag.textContent = `
210                            .vp-controls, .vp-sidedock, .vp-title, .vp-progress-bar-container {
211                                display: none !important;
212                                opacity: 0 !important;
213                                visibility: hidden !important;
214                            }
215                        `;
216                        document.head.appendChild(styleTag);
217                    } catch (e) {
218                        console.error('Error customizing Vimeo player:', e);
219                    }
220                }, 500);
221            }).catch(function(error) {
222                console.error('Player customization error:', error);
223            });
224        } catch (error) {
225            console.error('Error initializing Vimeo player:', error, 'for iframe:', iframe);
226        }
227    }
228    
229    function pauseAllOtherVideos(exceptPlayerId) {
230        for (const playerId in players) {
231            if (playerId !== exceptPlayerId) {
232                const player = players[playerId];
233                player.pause();
234                
235                const container = document.querySelector(`[data-
235player-id="${playerId}"]`);
236                if (container) {
237                    const overlay = container.querySelector('.video-overlay');
238                    const clickCatcher = container.querySelector('.video-click-catcher');
239                    if (overlay) {
240                        overlay.classList.remove('hidden');
241                    }
242                    if (clickCatcher) {
243                        clickCatcher.classList.remove('active');
244                    }
245                }
246            }
247        }
248    }
249})(); 

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.