1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// Deuxfleurs website script
// Author: Deuxfleurs association
// License: CC-BY-SA
// Version: 2.0
// Date: 2024
// Dictionary containing the animated frames' ID as key, and animation delay as value
const animationDelay = {
'illustration-accueil': 500,
'rennes': 1000,
'orsay': 2000,
'parterre': 1500
};
// Dictionary to keep track of frame count for each animation
let animationFrame = {};
// Dictionary to keep track of the animation callbacks in order to stop them
let animationCallback = {};
// Animations toggle switch (will be initialised in setupPage)
let isAnimated = false;
// Load the script once the document is ready
document.addEventListener('DOMContentLoaded', function() {
setupPage();
});
function setupPage() {
// Check if the user configured that they prefer reduced motion
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion)").matches;
// Set the animation toggle switch value to the user's configured prefers-reduced-motion
isAnimated = prefersReducedMotion;
// Play/pause button setup, such that it starts/stops the animations ...
document.getElementById("bouton-play-pause").addEventListener("click", pauseButtonClickedCallback);
// ... and has a content reflecting the animation state
setPauseButtonContent();
// Initialise the animations by looping through animationDelay keys
Object.keys(animationDelay).forEach((id) => initAnimation(id));
}
function initAnimation(id) {
// Initialise this ID's animationCallback value to null
animationCallback[id] = null;
// Start by displaying the 0th frame
animationFrame[id] = 0;
// Start the animation if authorised
if (isAnimated) {
startAnimation(id);
}
}
function startAnimation(id) {
// console.log(`Starting animation of frame '${id}' with delay of ${animationDelay[id]}ms.`);
const container = document.getElementById(id);
// Periodically calls updateAnimation with a certain `delay` and function parameters
// We store the callback identifier in animationCallback to be able to stop it
animationCallback[id] = setInterval(
updateAnimation,
animationDelay[id],
id, container.children, container.children.length
);
}
function updateAnimation(id, frames, nFrames) {
// Hide the current frame
frames[animationFrame[id]].style.display = "none";
// Increment the frame counter for the given id
animationFrame[id] = (animationFrame[id] + 1) % nFrames;
// Show the next frame
frames[animationFrame[id]].style.display = "flex";
}
function pauseButtonClickedCallback() {
// console.log('Play/pause button clicked');
// Toggle the isAnimated switch
isAnimated = !isAnimated;
// Update the animation status for each animated block
Object.keys(animationDelay).forEach((id) => {
if (isAnimated) {
// If animations were just authorised, start it
startAnimation(id);
} else {
// Else, stop it by calling clearInterval on the existing callback
clearInterval(animationCallback[id]);
}
});
setPauseButtonContent();
}
function setPauseButtonContent() {
// Set the button content corresponding to the animation state
if (isAnimated) {
document.getElementById("bouton-play-pause").innerHTML = "[⏸]";
} else {
document.getElementById("bouton-play-pause").innerHTML = "[⏵]";
}
}
|