2024-02-19 08:37:05 +00:00
// Loads the script once the document is ready
document . addEventListener ( 'DOMContentLoaded' , function ( ) {
setupPage ( ) ;
} ) ;
2024-02-02 09:43:48 +00:00
2024-02-19 08:37:05 +00:00
function setupPage ( ) {
// Checks if the user didn't enable prefers-reduced-motion
let animationEnabled = window . matchMedia ( '(prefers-reduced-motion: no-preference)' ) . matches ;
2024-02-19 08:48:41 +00:00
// Boolean to keep track of current animation state, starts at true because it is linked to the button which is only displayed when animationEnabled is true
let currentAnimationState = true ;
2024-02-15 14:33:38 +00:00
// Dictionary to keep track of animation intervals
2024-02-07 08:52:32 +00:00
let animationIntervals = { } ;
2024-02-15 14:33:38 +00:00
// Dictionary to keep track of delay count for each animation
2024-02-07 08:52:32 +00:00
let delays = { } ;
2024-02-15 14:33:38 +00:00
// Dictionary to keep track of frame for each animation
2024-02-07 08:52:32 +00:00
let frames = { } ;
2024-02-15 14:33:38 +00:00
// dictionary to keep track of frame count for each animation
2024-02-07 08:52:32 +00:00
let frameCounts = { } ;
2024-02-19 08:37:05 +00:00
// Buttons for toggling
const toggleable = document . querySelector ( '.toggleable' ) ;
const imgTopToggleable = document . querySelector ( '.img_top_toggleable' ) ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
const illustrationAccueil = document . getElementById ( 'illustration-accueil' ) ;
const rennes = document . getElementById ( 'rennes' ) ;
const orsay = document . getElementById ( 'orsay' ) ;
const parterre = document . getElementById ( 'parterre' ) ;
2024-02-02 10:03:55 +00:00
2024-02-15 14:33:38 +00:00
// Update ARIA live attributes based on prefers-reduced-motion
function setARIALiveAttributes ( isAnimated ) {
if ( isAnimated ) {
2024-02-07 08:52:32 +00:00
illustrationAccueil . setAttribute ( 'aria-live' , 'off' ) ;
rennes . setAttribute ( 'aria-live' , 'off' ) ;
orsay . setAttribute ( 'aria-live' , 'off' ) ;
parterre . setAttribute ( 'aria-live' , 'off' ) ;
} else {
illustrationAccueil . setAttribute ( 'aria-live' , 'polite' ) ;
rennes . setAttribute ( 'aria-live' , 'polite' ) ;
orsay . setAttribute ( 'aria-live' , 'polite' ) ;
parterre . setAttribute ( 'aria-live' , 'polite' ) ;
}
2024-02-02 09:59:02 +00:00
}
2024-02-07 08:52:32 +00:00
function animate ( id , delay ) {
2024-02-19 08:37:05 +00:00
// get the container and frames for the animation
2024-02-07 08:52:32 +00:00
const container = document . getElementById ( id ) ;
const framesList = container . children ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// set up the frame counter
frameCounts [ id ] = 0 ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// hide all frames except for the first
framesList [ 0 ] . style . display = "flex" ;
for ( let i = 1 ; i < framesList . length ; i ++ ) {
framesList [ i ] . style . display = "none" ;
}
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// Stock frames and delay in dictionaries
frames [ id ] = framesList ;
delays [ id ] = delay ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// Update ARIA live attributes
2024-02-15 14:33:38 +00:00
setARIALiveAttributes ( true ) ;
2024-02-02 09:59:02 +00:00
2024-02-15 14:33:38 +00:00
animationIntervals [ id ] = setInterval ( updateAnimation , delay , id , framesList , framesList . length ) ;
2024-02-02 09:43:48 +00:00
}
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
function updateAnimation ( id , framesList , totalFrames ) {
// increment the frame counter for the given id
frameCounts [ id ] = ( frameCounts [ id ] + 1 ) % totalFrames ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// show the next frame
framesList [ frameCounts [ id ] ] . style . display = "flex" ;
2023-10-17 07:51:32 +00:00
2024-02-07 08:52:32 +00:00
// hide the previous frame
if ( frameCounts [ id ] === 0 ) {
framesList [ totalFrames - 1 ] . style . display = "none" ;
} else {
framesList [ frameCounts [ id ] - 1 ] . style . display = "none" ;
}
2023-10-17 07:51:32 +00:00
}
2024-02-19 08:37:05 +00:00
// Start the animation if animation is enabled
2024-02-15 14:33:38 +00:00
if ( animationEnabled ) {
animate ( "illustration-accueil" , 500 ) ;
animate ( "rennes" , 1000 ) ;
animate ( "orsay" , 2000 ) ;
animate ( "parterre" , 1500 ) ;
}
2024-01-30 10:04:34 +00:00
2024-02-15 14:33:38 +00:00
const toggleableElements = document . querySelectorAll ( '.toggleable, .img_top_toggleable' ) ;
2024-02-19 08:37:05 +00:00
toggleableElements . forEach ( function ( element ) {
element . addEventListener ( 'click' , function ( ) {
2024-02-15 14:33:38 +00:00
toggleAnimation ( ) ;
2024-01-31 08:26:29 +00:00
} ) ;
2024-02-15 14:33:38 +00:00
} ) ;
2024-02-05 13:25:54 +00:00
2024-02-07 08:52:32 +00:00
function toggleAnimation ( ) {
2024-02-19 08:37:05 +00:00
// Play or pause the animations based on current state
2024-02-19 08:48:41 +00:00
if ( currentAnimationState ) {
2024-02-19 08:37:05 +00:00
// Pause the animations
2024-02-07 08:52:32 +00:00
toggleable . style . display = 'none' ;
imgTopToggleable . style . display = 'block' ;
2024-02-19 08:37:05 +00:00
setARIALiveAttributes ( false ) ;
2024-02-07 08:52:32 +00:00
Object . keys ( animationIntervals ) . forEach ( id => {
clearInterval ( animationIntervals [ id ] ) ;
} ) ;
2024-02-19 08:37:05 +00:00
} else {
// Play the animations
toggleable . style . display = 'block' ;
imgTopToggleable . style . display = 'none' ;
setARIALiveAttributes ( true ) ;
Object . keys ( animationIntervals ) . forEach ( id => {
animationIntervals [ id ] = setInterval ( updateAnimation , delays [ id ] , id , frames [ id ] , frames [ id ] . length ) ;
} ) ;
2024-02-07 08:52:32 +00:00
}
2024-02-19 08:37:05 +00:00
// Toggle animation state
2024-02-19 08:48:41 +00:00
currentAnimationState = ! currentAnimationState ;
2024-02-05 13:25:54 +00:00
}
2024-02-07 08:52:32 +00:00
let lastScrollTop = 0 ;
2024-02-09 08:49:22 +00:00
let isCallbackRegistered = false ;
2024-02-07 08:52:32 +00:00
window . addEventListener ( "scroll" , function ( ) {
2024-02-19 08:48:41 +00:00
const toggleButton = document . querySelectorAll ( '.toggleButton' ) ;
if ( animationEnabled ) {
if ( ! isCallbackRegistered ) {
window . requestAnimationFrame ( function ( ) {
let currentPosition = window . scrollY || document . documentElement . scrollTop ;
if ( currentPosition > lastScrollTop ) {
// Scroll down
toggleButton . forEach ( button => {
button . style . display = "none" ;
} ) ;
} else {
// Scroll up
toggleButton . forEach ( button => {
button . style . display = "block" ;
} ) ;
}
lastScrollTop = currentPosition <= 0 ? 0 : currentPosition ; // For Mobile or negative scrolling
isCallbackRegistered = false ;
} ) ;
isCallbackRegistered = true ;
}
}
else {
toggleButton . forEach ( button => {
button . style . display = "none" ;
2024-02-07 08:52:32 +00:00
} ) ;
}
} ) ;
}