tfrere commited on
Commit
7c1a5fc
·
1 Parent(s): fc42692
client/src/components/InfiniteBackground.jsx ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Box } from "@mui/material";
2
+ import { keyframes } from "@mui/system";
3
+ import { useState, useEffect } from "react";
4
+ import { motion, AnimatePresence } from "framer-motion";
5
+
6
+ const slideLeft = keyframes`
7
+ from {
8
+ transform: translateX(0);
9
+ }
10
+ to {
11
+ transform: translateX(-100%);
12
+ }
13
+ `;
14
+
15
+ const slideRight = keyframes`
16
+ from {
17
+ transform: translateX(0);
18
+ }
19
+ to {
20
+ transform: translateX(100%);
21
+ }
22
+ `;
23
+
24
+ // Hook pour précharger l'image et obtenir ses dimensions
25
+ const useImageDimensions = (imagePath) => {
26
+ const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
27
+ const [isLoaded, setIsLoaded] = useState(false);
28
+
29
+ useEffect(() => {
30
+ const img = new Image();
31
+ img.src = imagePath;
32
+ img.onload = () => {
33
+ setDimensions({ width: img.width, height: img.height });
34
+ setIsLoaded(true);
35
+ };
36
+ }, [imagePath]);
37
+
38
+ return { dimensions, isLoaded };
39
+ };
40
+
41
+ const Row = ({ imagePath, direction = "left", speed = 1, containerHeight }) => {
42
+ const { dimensions, isLoaded } = useImageDimensions(imagePath);
43
+ const animation = direction === "left" ? slideLeft : slideRight;
44
+ const duration = 120 / speed;
45
+
46
+ if (!isLoaded) return null;
47
+
48
+ // Calculer la hauteur de l'image pour qu'elle s'adapte à la hauteur du conteneur
49
+ const scale = containerHeight / dimensions.height;
50
+ const scaledWidth = dimensions.width * scale;
51
+
52
+ return (
53
+ <motion.div
54
+ initial={{ opacity: 0 }}
55
+ animate={{ opacity: 1 }}
56
+ transition={{ duration: 1 }}
57
+ >
58
+ <Box
59
+ sx={{
60
+ position: "relative",
61
+ width: "100%",
62
+ height: containerHeight,
63
+ overflow: "hidden",
64
+ display: "flex",
65
+ }}
66
+ >
67
+ {/* Premier set d'images */}
68
+ <Box
69
+ sx={{
70
+ display: "flex",
71
+ animation: `${animation} ${duration}s linear infinite`,
72
+ height: "100%",
73
+ }}
74
+ >
75
+ {[1, 2, 3].map((i) => (
76
+ <img
77
+ key={i}
78
+ src={imagePath}
79
+ alt="panorama"
80
+ style={{
81
+ height: containerHeight,
82
+ width: scaledWidth,
83
+ objectFit: "contain",
84
+ }}
85
+ />
86
+ ))}
87
+ </Box>
88
+ {/* Second set d'images pour la boucle continue */}
89
+ <Box
90
+ sx={{
91
+ display: "flex",
92
+ animation: `${animation} ${duration}s linear infinite`,
93
+ position: "absolute",
94
+ left: direction === "left" ? "100%" : `-${scaledWidth * 3}px`,
95
+ height: "100%",
96
+ }}
97
+ >
98
+ {[1, 2, 3].map((i) => (
99
+ <img
100
+ key={i}
101
+ src={imagePath}
102
+ alt="panorama"
103
+ style={{
104
+ height: containerHeight,
105
+ width: scaledWidth,
106
+ objectFit: "contain",
107
+ }}
108
+ />
109
+ ))}
110
+ </Box>
111
+ </Box>
112
+ </motion.div>
113
+ );
114
+ };
115
+
116
+ export function InfiniteBackground() {
117
+ const [containerHeight, setContainerHeight] = useState(0);
118
+
119
+ useEffect(() => {
120
+ const updateHeight = () => {
121
+ const vh = window.innerHeight;
122
+ setContainerHeight(vh / 3); // Divise la hauteur de la fenêtre en 3
123
+ };
124
+
125
+ updateHeight();
126
+ window.addEventListener("resize", updateHeight);
127
+ return () => window.removeEventListener("resize", updateHeight);
128
+ }, []);
129
+
130
+ return (
131
+ <Box
132
+ sx={{
133
+ position: "absolute",
134
+ top: 0,
135
+ left: 0,
136
+ right: 0,
137
+ bottom: 0,
138
+ overflow: "hidden",
139
+ zIndex: 0,
140
+ "&::after": {
141
+ content: '""',
142
+ position: "absolute",
143
+ top: 0,
144
+ left: 0,
145
+ right: 0,
146
+ bottom: 0,
147
+ background: "rgba(0, 0, 0, 0.85)",
148
+ zIndex: 1,
149
+ },
150
+ }}
151
+ >
152
+ <Row
153
+ imagePath="/bande-1.webp"
154
+ direction="left"
155
+ speed={1}
156
+ containerHeight={containerHeight}
157
+ />
158
+ <Row
159
+ imagePath="/bande-2.webp"
160
+ direction="right"
161
+ speed={0.8}
162
+ containerHeight={containerHeight}
163
+ />
164
+ <Row
165
+ imagePath="/bande-3.webp"
166
+ direction="left"
167
+ speed={1.2}
168
+ containerHeight={containerHeight}
169
+ />
170
+ </Box>
171
+ );
172
+ }
client/src/pages/Home.jsx CHANGED
@@ -4,6 +4,7 @@ import { useNavigate } from "react-router-dom";
4
  import { usePageSound } from "../hooks/usePageSound";
5
  import { BlinkingText } from "../components/BlinkingText";
6
  import { BookPages } from "../components/BookPages";
 
7
 
8
  export function Home() {
9
  const navigate = useNavigate();
@@ -31,40 +32,9 @@ export function Home() {
31
  minHeight: "100vh",
32
  width: "100%",
33
  position: "relative",
34
- "&::before": {
35
- content: '""',
36
- position: "fixed",
37
- top: 0,
38
- left: 0,
39
- right: 0,
40
- bottom: 0,
41
- backgroundImage: "url('/home.webp')",
42
- backgroundSize: "cover",
43
- backgroundPosition: "center",
44
- backgroundRepeat: "no-repeat",
45
- opacity: 0.3,
46
- zIndex: 0,
47
- },
48
  }}
49
  >
50
- {/* <Typography
51
- variant="h1"
52
- component="h1"
53
- sx={{
54
- fontWeight: "bold",
55
- marginBottom: 2,
56
- color: "#f0e6d9",
57
- textShadow: `
58
- 0 -1px 1px rgba(0,0,0,0.3),
59
- 0 1px 1px rgba(255,255,255,0.2)
60
- `,
61
- letterSpacing: "0.5px",
62
- filter: "brightness(0.95)",
63
- }}
64
- >
65
- Sarah's
66
- <br /> Chronicles
67
- </Typography> */}
68
  <Box
69
  sx={{
70
  position: "relative",
 
4
  import { usePageSound } from "../hooks/usePageSound";
5
  import { BlinkingText } from "../components/BlinkingText";
6
  import { BookPages } from "../components/BookPages";
7
+ import { InfiniteBackground } from "../components/InfiniteBackground";
8
 
9
  export function Home() {
10
  const navigate = useNavigate();
 
32
  minHeight: "100vh",
33
  width: "100%",
34
  position: "relative",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }}
36
  >
37
+ <InfiniteBackground />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  <Box
39
  sx={{
40
  position: "relative",
client/src/pages/Tutorial.jsx CHANGED
@@ -271,31 +271,6 @@ export function Tutorial() {
271
  Start the game
272
  </Button>
273
  </Box>
274
- <Box
275
- sx={{
276
- display: "flex",
277
- flexDirection: "column",
278
- alignItems: "center",
279
- justifyContent: "center",
280
- minHeight: "100vh",
281
- width: "100%",
282
- position: "relative",
283
- "&::before": {
284
- content: '""',
285
- position: "fixed",
286
- top: 0,
287
- left: 0,
288
- right: 0,
289
- bottom: 0,
290
- backgroundImage: "url('/home.webp')",
291
- backgroundSize: "cover",
292
- backgroundPosition: "center",
293
- backgroundRepeat: "no-repeat",
294
- opacity: 0.3,
295
- zIndex: 0,
296
- },
297
- }}
298
- ></Box>
299
  </motion.div>
300
  );
301
  }
 
271
  Start the game
272
  </Button>
273
  </Box>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  </motion.div>
275
  );
276
  }