$(document).ready( () => { lazyLoading() displayPictograms() getDeviceSize() hideMobileNavOnResize() hoverDesktopNavItems() if (currentPage.text().trim() == 'Accueil') { hideFooter() animateText() } else if (currentPage.text().trim() == 'Projets' && $('main').children(":first").attr('id') != 'reader') { hideFooter() loadProjetIndex() } else if ($('main').children(":first").attr('id') == 'reader') { hideFooter() displayReader() } initBarba() }) // GLOBAL VARIABLES let isMobileNavOpen = false, isDesktopDevice = false, currentPage, indexIsReady = false, filterObj = { publiqueCardsDisplayed : true, socialeCardsDisplayed : true, culturelleCardsDisplayed : true }, projectTitleIsScrolling = false, titleScrollTimer // MAIN FUNCTIONS function initBarba() { barba.init({ prefetchIgnore: true, transitions: [{ name: 'opacity-transition', leave(data) { return gsap.to(data.current.container, { opacity: 0 }) }, enter(data) { return gsap.from(data.next.container, { opacity: 0 }) } }] }) barba.hooks.beforeLeave((data) => { if (isMobileNavOpen) { toggleMobileNav() } if ($(data.current.container).attr('id') == 'projets-index') { resetFilters() } if ($(data.current.container).attr('id') == 'text-content' ) { hideFooter() } }) barba.hooks.afterLeave((data) => { if ($(data.current.container).attr('id') == 'reader') { if ($(data.next.container).attr('id') != 'reader') { leaveReader() $('#nav-container h1').empty().append(currentPage.text()) } } }) barba.hooks.beforeEnter((data) => { lazyLoading() displayPictograms() $('html, body').scrollTop(0) if ($(data.next.container).attr('id') == 'index-content') { animateText() indexIsReady = false } else if ($(data.next.container).attr('id') == 'projets-index') { loadProjetIndex() filterWhenEntering() } else if ($(data.next.container).attr('id') == 'text-content') { if (isDesktopDevice) { displayFooter() } } }) barba.hooks.after((data) => { let pageTitleComparator, navIndex switch ($('main').children(":first").attr('id')) { case 'index-content': pageTitleComparator = 'Accueil' navIndex = 0 break case 'text-content': // dirty hack to get what content it is if ($('main').children(":first").children(":first").text().substring(3).replace(/ .*/,'') == "équipe") { pageTitleComparator = 'Le collectif' navIndex = 1; } else { pageTitleComparator = 'Logiciels Libres' navIndex = 3; } break case 'projets-index': case 'reader': pageTitleComparator = 'Projets' navIndex = 2 break } if (pageTitleComparator != currentPage.text().trim()) { changeMenuSelected($('header nav ul li').eq(navIndex)) } if ($(data.next.container).attr('id') == 'reader') { displayReader() } }) } function lazyLoading() { $('.lazy').Lazy({ scrollDirection: 'vertical', effect: 'fadeIn', effectTime: 400, threshold: 100, afterLoad: function(element) { $(element).removeClass('loader') if ($(element).parent().is('figure')) { $(element).parent().addClass('loaded') } else { $(element).parentsUntil('figure').parent().addClass('loaded') } } }) } // UI FUNCTIONS // general content function displayPictograms() { // To be able to change the pictograms color through scss variables addLinkPictogram() $('.picto').each((i, el) => { let source = $(el).data('src') $(el).css({ '-webkit-mask': 'url(' + source + ') 0% 0% / contain no-repeat', 'mask': 'url(' + source + ') 0% 0% / contain no-repeat', }) }) } function addLinkPictogram() { $('main a[target="_blank"]').each( (i, e) => { $(e).append('
') }) // hardcoded url because cant use twig in js } function getDeviceSize() { function setDeviceSize() { if (window.matchMedia('(min-width: 996px)').matches) { isDesktopDevice = true } else { isDesktopDevice = false } } setDeviceSize() let timer $(window).on('resize', () => { clearTimeout(timer) timer = setTimeout(setDeviceSize(), 100) refreshUiOnResize() }) } function refreshUiOnResize() { hideFooterOnResize() hideMobileNavOnResize() checkTitleAutoScroll() } function triggerLazyLoading() { setTimeout(() => { $(document).scrollTop($(document).scrollTop() + 1) setTimeout(() => { $(document).scrollTop($(document).scrollTop() - 1) }, 100) }, 300) } function titleScrollTop() { if ($('html, body').scrollTop() > 0) { $('html, body').animate({scrollTop: 0}, 1200) if (currentPage.text().trim() == 'Accueil') { toggleIndexContent(true) } } } // set navigation function toggleMobileNav() { if (!isMobileNavOpen) { $('nav').addClass('mobile-nav-open') $('footer').fadeIn() isMobileNavOpen = true } else { $('nav').removeClass('mobile-nav-open') isMobileNavOpen = false if (window.matchMedia('(min-width: 576px)').matches && (currentPage.text().trim() == 'Figures Libres' || currentPage.text().trim() == 'Logiciels Libres')) { return } else { $('footer').fadeOut() } } } function hideMobileNavOnResize() { if (!isDesktopDevice) { if (isMobileNavOpen) { toggleMobileNav() } $('nav').css('display', 'none') setTimeout( () => { $('nav').css('display', 'flex') }, 200) } } function hoverDesktopNavItems() { currentPage = $('.selected') $('nav li').hover(() => { if (isDesktopDevice) { currentPage.removeClass('selected') } }, () => { if (isDesktopDevice) { currentPage.addClass('selected') } }) } function changeMenuSelected(page) { $('.selected').removeClass('selected') currentPage = $(page) currentPage.addClass('selected') changeMobileTitle() } function changeMobileTitle() { $('#nav-container h1').empty().append(currentPage.text()) } // index interaction function toggleIndexContent(closeEverything) { let isTextOpen = false, isCommanditairesOpen = false, isExtraitOpen = false, quelExtrait if (closeEverything) { closeEverything() } $('#second-p-index, #commanditaires-grid, #extrait-publique, #extrait-social, #extrait-culturelle').children().fadeOut() $('#arrowIndex').click( () => { if (!isTextOpen && !isExtraitOpen) { if (isDesktopDevice) { displayContent($('#second-p-index'), '70vh') } else { displayContent($('#second-p-index'), '90vh') } turnArrow('down') isTextOpen = true } else { if (isExtraitOpen) { hideContent($('#extrait-' + quelExtrait)) $('#' + quelExtrait).css('text-decoration', 'none') isExtraitOpen = false turnArrow('top') } if (isTextOpen) { hideContent($('#second-p-index')) turnArrow('top') isTextOpen = false } if (isCommanditairesOpen) { hideContent($('#commanditaires-grid')) $('#commanditaires').css('text-decoration', 'none') isCommanditairesOpen = false } } }) $('#index-content canvas').click( function(event) { target = $(event.target).parent().attr('id') if (target == 'publique' || target == 'sociale' || target == 'culturelle') { toggleExtrait(target) return false } else if (target == 'commanditaires') { toggleCommanditaires() return false } else { switch (target) { case 'figureslibres': changeMenuSelected($('nav li a[href$=collectif]').parent()) break case 'logicielslibres': changeMenuSelected($('nav li a[href$=logiciels-libres]').parent()) break case 'projets': changeMenuSelected($('nav li a[href$=projets]').parent()) break } } }) $('#extrait-projets .projets-link-filter').click(() => { changeMenuSelected($('nav li a[href$=projets]').parent()) }) function toggleExtrait(category) { if(!isExtraitOpen) { if (isTextOpen) { hideContent($('#second-p-index')) isTextOpen = false } if (isCommanditairesOpen) { hideContent($('#commanditaires-grid')) $('#commanditaires').css('text-decoration', 'none') isCommanditairesOpen = false } displayContent($('#extrait-' + category), '80vh') turnArrow('down') $('#' + category).css({'text-decoration': 'underline', 'text-decoration-thickness': '2px', 'text-underline-offset': '8px'}) isExtraitOpen = true quelExtrait = category } else if (isExtraitOpen && quelExtrait != category) { hideContent($('#extrait-' + quelExtrait)) $('#' + category).css({'text-decoration': 'underline', 'text-decoration-thickness': '2px', 'text-underline-offset': '8px'}) $('#' + quelExtrait).css('text-decoration', 'none') setTimeout(() => { displayContent($('#extrait-' + category), '80vh') quelExtrait = category }, 1000) } else if (isExtraitOpen && quelExtrait == category) { hideContent($('#extrait-' + category)) turnArrow('top') $('#' + category).css('text-decoration', 'none') isExtraitOpen = false } } function toggleCommanditaires() { if (!isCommanditairesOpen) { displayContent($('#commanditaires-grid'), '150vh') $('#commanditaires').css({'text-decoration': 'underline', 'text-decoration-thickness': '2px', 'text-underline-offset': '8px'}) isCommanditairesOpen = true } else { hideContent($('#commanditaires-grid')) $('#commanditaires').css('text-decoration', 'none') isCommanditairesOpen = false } } function closeEverything() { if (isTextOpen) { hideContent($('#second-p-index')) isTextOpen = false } if (isExtraitOpen) { hideContent($('#extrait-' + quelExtrait)) $('#' + quelExtrait).css('text-decoration', 'none') isExtraitOpen = false } if (isCommanditairesOpen) { hideContent($('#commanditaires-grid')) $('#commanditaires').css('text-decoration', 'none') isCommanditairesOpen = false } turnArrow('top') } } function turnArrow(direction) { if (direction == 'down') { $('#arrow-container').css({ 'transform': 'rotate(180deg)', 'margin-bottom': '10vh' }) $('#arrow-container .picto').removeAttr('id') } else if (direction == 'top') { $('#arrow-container').css({ 'transform': 'rotate(0deg)', 'margin-bottom': '0vh' }) $('#arrow-container .picto').attr('id', 'arrowIndex') } } function displayContent(content, maxHeight) { content.children().fadeIn() setTimeout( () => { content.css({ 'max-height': maxHeight, 'opacity': '1' }) if (isDesktopDevice) { content.css('margin-top', '3vh') } }, 200) setTimeout( () => { $('html, body').animate({ scrollTop: $(content).position().top }, 1200, 'swing') }, 400) } function hideContent(content) { content.css({ 'max-height': '0vh', 'opacity': '0', 'margin-top': '0vh' }) setTimeout(() => { content.children().fadeOut() }, 1200) } // index animation function animateText() { waitForWebfonts(['Moche'], () => { // idk why listing only one font makes it work.... // For each item $(".animateText").each(function(i, e) { $(e).contents().wrap('') $('#main-p-index span').css('color', 'transparent') $('#second-p-index span').css('color', 'transparent') // Initialize a new LiquidText instance var liquidText = new LiquidText( e, // Element 0.0, // Liquid Volatility 0.5 // Speed ).start() }) toggleIndexContent() displayIndexWhenReady() }) } let globalMaterial = new Blotter.LiquidDistortMaterial() let globalBlotter = new Blotter(globalMaterial, { texts: [], autostart: false, autobuild: false }) class LiquidText { constructor(element, volatility, speed) { this.element = element this.text = element.text this.fontSize = parseInt($(element).css('font-size')) this.fontStack = $(element).css('font-family') this.fontWeight = $(element).css('font-weight') this.fontColor = $(element).css('color') this.material = globalMaterial this.hoverDuration = 0.35 this.hoverEase = Linear.easeIn this.liquidVolatility = volatility this.liquidSpeed = speed this.scope = null this.blotter = globalBlotter this.blotterText = null this.onResize = this.onResize.bind(this) this.seed = 0.1 window.addEventListener('resize', this.onResize) this.initialize() } initialize() { let blotter = this.blotter let text = new Blotter.Text(this.text, { family: this.fontStack, size: this.fontSize, fill: this.fontColor, weight: this.fontWeight, paddingLeft: 15, paddingRight: 15 }) this.blotterText = text this.material.uniforms.uSpeed.value = this.liquidSpeed this.material.uniforms.uVolatility.value = this.liquidVolatility blotter.addText(text) blotter.needsUpdate = true var scope = blotter.forText(text) this.scope = scope scope.appendTo(this.element) this.material.needsUpdate = true gsap.fromTo(this.material.uniforms.uVolatility, this.hoverDuration, { value: 0, ease: this.hoverEase }, { value: this.liquidVolatility, ease: this.hoverEase }) this.element.onmouseenter = (event) => { this.scope.material.needsUpdate = true gsap.fromTo(this.scope.material.uniforms.uVolatility, this.hoverDuration, { value: 0, ease: this.hoverEase }, { value: this.liquidVolatility + 0.04, ease: this.hoverEase }) } this.element.onmouseleave = (event) => { gsap.fromTo(this.scope.material.uniforms.uVolatility, this.hoverDuration, { value: this.scope.material.uniforms.uVolatility.value, ease: this.hoverEase }, { value: this.liquidVolatility, ease: this.hoverEase, onComplete: () => { this.scope.material.needsUpdate = true } }) } } stop() { this.blotter.stop() } start() { this.blotter.start() } onResize() { let text = this.blotterText let time = 100 let timer if(timer) clearTimeout(timer) timer = setTimeout(() => { text.properties.size = parseInt($(this.element).css('font-size')) text.needsUpdate = true }, time, event) } } function displayIndexWhenReady() { globalBlotter.on('update', () => { if (!indexIsReady) { indexIsReady = true $('#loader-index').fadeOut(1400) } }) } function waitForWebfonts(fonts, callback) { var loadedFonts = 0 for (var i = 0, l = fonts.length; i < l; ++i) { ((font) => { var node = document.createElement('span') // Characters that vary significantly among different fonts node.innerHTML = 'giItT1WQy@!-/#' // Visible - so we can measure it - but not on the screen node.style.position = 'absolute' node.style.left = '-10000px' node.style.top = '-10000px' // Large font size makes even subtle changes obvious node.style.fontSize = '300px' // Reset any font properties node.style.fontFamily = 'sans-serif' node.style.fontVariant = 'normal' node.style.fontStyle = 'normal' node.style.fontWeight = 'normal' node.style.letterSpacing = '0' document.body.appendChild(node) // Remember width with no applied web font var width = node.offsetWidth node.style.fontFamily = font + ', sans-serif' var interval function checkFont() { // Compare current width with original width if (node && node.offsetWidth != width) { ++loadedFonts node.parentNode.removeChild(node) node = null } // If all fonts have been loaded if (loadedFonts >= fonts.length) { if (interval) { clearInterval(interval) } if (loadedFonts == fonts.length) { callback() return true } } } if (!checkFont()) { interval = setInterval(checkFont, 50) } })(fonts[i]) } } // display project grid function toggleCategory(category) { let chevron = $(category).find('.chevron-category') if (chevron.hasClass('close')) { $(chevron.removeClass('close')) $(category).next().slideToggle('slow') $('.card-displayed figure').each(function() { if ($(this).css('transform') != 'none') { $(this).css('transform', 'none') } }) } else { $(chevron.addClass('close')) $(category).next().slideToggle('slow') triggerLazyLoading() } } function filterCards(utilite) { let filterIsOn function checkFilter() { switch (utilite) { case 'publique': filterIsOn = filterObj.publiqueCardsDisplayed ? true : false if (filterObj.publiqueCardsDisplayed) { filterObj.publiqueCardsDisplayed = false } else { filterObj.publiqueCardsDisplayed = true } break case 'sociale': filterIsOn = filterObj.socialeCardsDisplayed ? true : false if (filterObj.socialeCardsDisplayed) { filterObj.socialeCardsDisplayed = false } else { filterObj.socialeCardsDisplayed = true } break case 'culturelle': filterIsOn = filterObj.culturelleCardsDisplayed ? true : false if (filterObj.culturelleCardsDisplayed) { filterObj.culturelleCardsDisplayed = false } else { filterObj.culturelleCardsDisplayed = true } break } } if (Object.values(filterObj).every(Boolean) || Object.values(filterObj).every(e => e == false)) { // si tous les filtres sont actifs (état de base) $('.projets-grid div').each(function () { // hide all cards if($(this).hasClass(utilite + '-card')) { // except those from the filtered category $(this).removeClass('card-hidden').addClass('card-displayed') } else { $(this).removeClass('card-displayed').addClass('card-hidden') } }) $('#' + utilite + '-filter').css('opacity', 1) Object.keys(filterObj).forEach(v => filterObj[v] = false) checkFilter() } else if (Object.values(filterObj).filter(Boolean).length == 1) { // check if the filter is on or off checkFilter() if (filterIsOn) { $('#' + utilite + '-filter').css('opacity', 0.4) $('.projets-grid div').each(function () { // display all cards $(this).removeClass('card-hidden').addClass('card-displayed') }) } else { $('#' + utilite + '-filter').css('opacity', 1) $('.' + utilite + '-card').each(function () { // only display cards from selected category $(this).removeClass('card-hidden').addClass('card-displayed') }) } } else if (Object.values(filterObj).filter(Boolean).length == 2) { checkFilter() if (filterIsOn) { $('#' + utilite + '-filter').css('opacity', 0.4) $('.' + utilite + '-card').each(function () { // only display cards from selected category $(this).removeClass('card-displayed').addClass('card-hidden') }) } else { $('.filter-button').each(function() { $(this).css('opacity', 0.4) }) $('.projets-grid div').each(function () { // hide all cards $(this).removeClass('card-hidden').addClass('card-displayed') }) } } triggerLazyLoading() checkIfCategoryEmpty() // to hide empty category function checkIfCategoryEmpty() { $('.projets-grid').each(function() { let hiddenCount = 0 $(this).children().each(function() { if ($(this).hasClass('card-hidden')) { hiddenCount++ } }) if (hiddenCount == $(this).children().length) { $(this).prev().fadeOut() } else { $(this).prev().fadeIn() } }) } } function loadProjetIndex() { animateProjectGrid() isProjetsIndexLoaded = true } function animateProjectGrid() { const grid = document.querySelector(".projets-grid") animateCSSGrid.wrapGrid(grid, {duration : 600}) } function resetFilters() { Object.keys(filterObj).forEach(v => filterObj[v] = false) } function filterWhenEntering() { let searchParam = new URLSearchParams(window.location.search) if (searchParam.has('filter')) { switch (searchParam.get('filter')) { case 'publique': filterCards('publique') break case 'sociale': filterCards('sociale') break case 'culturelle': filterCards('culturelle') break } } } // display reader function displayReader() { $('.owl-carousel').owlCarousel() // initCarrousel() $('header').fadeOut() projectTitleIsScrolling = false checkTitleAutoScroll() let isProjectHeaderDisplayed = false $(window).scroll( () => { if ($(window).scrollTop() > $('#main-project-title').offset().top && !isProjectHeaderDisplayed) { $('#header-project').css('top', '0vh') if(isDesktopDevice) { $('#close-project').addClass('scrolled-cross') } isProjectHeaderDisplayed = true } else if ($(window).scrollTop() < $('#main-project-title').offset().top && isProjectHeaderDisplayed) { $('#header-project').css('top', '-9vh') if (isDesktopDevice) { $('#close-project').removeClass('scrolled-cross') } isProjectHeaderDisplayed = false } }) } function leaveReader() { $(window).off('scroll') $('header').fadeIn() if (!$('nav li a[href$=projets]').parent().hasClass('selected')) { changeNavSelected('projets') } disableTitleAutoScroll() } function titleAutoScroll() { if (!projectTitleIsScrolling) { $('#header-project').append('') projectTitleIsScrolling = true } $('#header-project h2 span').addClass('scrollText') $('#header-project h2 span').css({ 'transition': 'transform 7s linear', 'transform': 'translate(-' + parseInt($('#header-project h2 span').width() / 2 + 8) + 'px, 0)' }) titleScrollTimer = setTimeout( () => { $('#header-project h2 span').css({'transition': 'none', 'transform': 'translate(0, 0)'}) titleAutoScroll() }, 7000) } function disableTitleAutoScroll() { $('#gradient-long-title').remove() $('#header-project h2 span').removeClass('scrollText').css({'transition': 'none', 'transform': 'translate(0, 0)'}) projectTitleIsScrolling = false } function checkTitleAutoScroll() { if (titleScrollTimer != null) { clearTimeout(titleScrollTimer) } if ($('#header-project h2 span').width() > $('#header-project h2').width() && !projectTitleIsScrolling) { titleAutoScroll() } else if ($('#header-project h2 span').width() / 2 < $('#header-project h2').width() && projectTitleIsScrolling) { $('#header-project h2 span').removeClass('scrollText') disableTitleAutoScroll() } } // function initCarrousel() { // let isCarrouselOpen = false, currentImg // $('#reader img').each((i, el) => { // $(el).on('click', () => { // if (!isCarrouselOpen) { displayCarrousel(el) } // }) // }) // $('#bg-carrousel').on('click', () => { // hideCarrousel() // }) // function displayCarrousel(img) { // // if ($(img).attr('src') == $('#cover-image img').attr('src')) { // // $('#arrow-left .picto').addClass('disabled') // // } else { // // $('#arrow-left .picto').removeClass('disabled') // // } // // if ($(img).attr('src') == $('#reader img').last().attr('src')) { // // $('#arrow-right .picto').addClass('disabled') // // } else { // // $('#arrow-right .picto').removeClass('disabled') // // } // $('#reader #carrousel figure img').attr('src', $(img).attr('src')) // currentImg = $(img) // $('#arrow-left').on('click', () => { // $('#reader #carrousel figure img').attr('src', $(currentImg).parent().prev().children().first().attr('src')) // currentImg = $(currentImg).parent().prev().children().first() // }) // $('#arrow-right').on('click', () => { // $('#reader #carrousel figure img').attr('src', $(currentImg).parent().next().children().first().attr('src')) // currentImg = $(currentImg).parent().next().children().first() // }) // $('#carrousel').css('display', 'block') // isCarrouselOpen = true // } // function hideCarrousel() { // $('#carrousel').css('display', 'none') // isCarrouselOpen = false // } // } // show and hide footer function displayFooter() { $('footer').fadeIn() } function hideFooter() { $('footer').fadeOut() } function hideFooterOnResize() { if ($('footer').css('display', 'flex') && (window.matchMedia('(max-width: 576px)').matches || $('.selected').text().trim() == 'Accueil' || $('.selected').text().trim() == 'Projets')) { $('footer').css('display', 'none') } }