Skip to content

Commit 5491abb

Browse files
committed
add full screen mode on image click
1 parent 3f29b3a commit 5491abb

3 files changed

Lines changed: 151 additions & 5 deletions

File tree

src/BounceCards/BounceCards.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const useStyles = createUseStyles({
1818
border: '5px solid #fff',
1919
borderRadius: 25,
2020
overflow: 'hidden',
21-
boxShadow: '0 4px 10px rgba(0, 0, 0, 0.2)'
21+
boxShadow: '0 4px 10px rgba(0, 0, 0, 0.2)',
22+
cursor: 'pointer'
2223
},
2324
image: {
2425
width: '100%',
@@ -38,6 +39,7 @@ export interface BounceCardsProps {
3839
transformStyles?: string[];
3940
enableHover?: boolean;
4041
cardSize?: number;
42+
onImageClick?: (src: string) => void;
4143
}
4244

4345
export default function BounceCards({
@@ -56,7 +58,8 @@ export default function BounceCards({
5658
'rotate(2deg) translate(170px)'
5759
],
5860
enableHover = true,
59-
cardSize = 200
61+
cardSize = 200,
62+
onImageClick
6063
}: BounceCardsProps) {
6164
const classes = useStyles();
6265
const cardsRef = useRef<(HTMLDivElement | null)[]>([]);
@@ -154,6 +157,12 @@ export default function BounceCards({
154157
});
155158
};
156159

160+
const handleCardClick = (src: string) => {
161+
if (onImageClick) {
162+
onImageClick(src);
163+
}
164+
};
165+
157166
return (
158167
<div
159168
className={`${classes.bounceCardsContainer} ${className}`}
@@ -178,6 +187,7 @@ export default function BounceCards({
178187
}}
179188
onMouseEnter={() => pushSiblings(idx)}
180189
onMouseLeave={resetSiblings}
190+
onClick={() => handleCardClick(src)}
181191
>
182192
<img className={classes.image} src={src} alt={`card-${idx}`} />
183193
</div>

src/Globe/GlobeMap.stories.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ CustomStyling.args = {
6666
'https://carlrocks.com/assets/images/prague2-7cfa719e695cf5a70189a1f04e962fcb.jpg', // River and forest
6767
'https://carlrocks.com/assets/images/bridge2-97fdff535d74995897b5e2af59f9e023.jpg', // Nature landscape
6868
'https://carlrocks.com/assets/images/clock2-c6eb3e18a6a8197c40941e3fba671db2.jpg', // Mountain and lake
69-
'https://carlrocks.com/assets/images/church-842d95a972602c9b593446e924fc8eb0.JPG' // Birds on a branch
69+
'https://carlrocks.com/assets/images/church-842d95a972602c9b593446e924fc8eb0.JPG', // Birds on a branch
70+
'https://picsum.photos/id/1011/600/600', // Girl with a camera
71+
'https://picsum.photos/id/1012/600/600', // Person looking at mountains
72+
'https://picsum.photos/id/1027/600/600', // Man in the desert
73+
'https://picsum.photos/id/1035/600/600', // Desert landscape
74+
'https://picsum.photos/id/1039/600/600' // City skyline
7075
]
7176
},
7277
{

src/Globe/GlobeMap.tsx

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,67 @@ const useStyles = createUseStyles({
8080
'.mapboxgl-ctrl-attrib-inner': {
8181
display: 'none !important'
8282
}
83+
},
84+
modal: {
85+
position: 'fixed',
86+
top: 0,
87+
left: 0,
88+
right: 0,
89+
bottom: 0,
90+
backgroundColor: 'rgba(0, 0, 0, 0.9)',
91+
display: 'flex',
92+
justifyContent: 'center',
93+
alignItems: 'center',
94+
zIndex: 1000,
95+
cursor: 'pointer'
96+
},
97+
modalImage: {
98+
maxWidth: '90vw',
99+
maxHeight: '90vh',
100+
objectFit: 'contain',
101+
borderRadius: 8
102+
},
103+
closeButton: {
104+
position: 'absolute',
105+
top: 20,
106+
right: 20,
107+
color: 'white',
108+
fontSize: 30,
109+
cursor: 'pointer',
110+
width: 40,
111+
height: 40,
112+
display: 'flex',
113+
justifyContent: 'center',
114+
alignItems: 'center',
115+
borderRadius: '50%',
116+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
117+
'&:hover': {
118+
backgroundColor: 'rgba(255, 255, 255, 0.2)'
119+
}
120+
},
121+
navButton: {
122+
position: 'absolute',
123+
top: '50%',
124+
transform: 'translateY(-50%)',
125+
color: 'white',
126+
fontSize: 40,
127+
cursor: 'pointer',
128+
width: 60,
129+
height: 60,
130+
display: 'flex',
131+
justifyContent: 'center',
132+
alignItems: 'center',
133+
borderRadius: '50%',
134+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
135+
'&:hover': {
136+
backgroundColor: 'rgba(255, 255, 255, 0.2)'
137+
},
138+
'&.prev': {
139+
left: 20
140+
},
141+
'&.next': {
142+
right: 20
143+
}
83144
}
84145
});
85146

@@ -131,6 +192,14 @@ const calculateColorFromCoordinates = (longitude: number, latitude: number): str
131192
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
132193
};
133194

195+
// Add this function before the GlobeMap component
196+
const getRandomImages = (images: string[], count: number = 5): string[] => {
197+
if (images.length <= count) return images;
198+
199+
const shuffled = [...images].sort(() => 0.5 - Math.random());
200+
return shuffled.slice(0, count);
201+
};
202+
134203
export function GlobeMap({
135204
width = '100%',
136205
height = 500,
@@ -149,6 +218,8 @@ export function GlobeMap({
149218
const [viewState, setViewState] = useState(initialViewState);
150219
const [selectedMarker, setSelectedMarker] = useState<MarkerData | null>(null);
151220
const [showCards, setShowCards] = useState(false);
221+
const [selectedImage, setSelectedImage] = useState<string | null>(null);
222+
const [currentImageIndex, setCurrentImageIndex] = useState<number>(0);
152223
const mapRef = useRef(null);
153224
const classes = useStyles();
154225
console.log(showCards);
@@ -197,7 +268,7 @@ export function GlobeMap({
197268
// Reset cards when selected marker changes
198269
useEffect(() => {
199270
if (!selectedMarker) {
200-
// setShowCards(false);
271+
setShowCards(false);
201272
}
202273
}, [selectedMarker]);
203274

@@ -215,6 +286,39 @@ export function GlobeMap({
215286
return () => clearInterval(rotationInterval);
216287
}, [enableAnimation]);
217288

289+
const handleModalClick = (e: React.MouseEvent) => {
290+
if (e.target === e.currentTarget) {
291+
setSelectedImage(null);
292+
}
293+
};
294+
295+
const handleCloseClick = () => {
296+
setSelectedImage(null);
297+
};
298+
299+
const handleImageClick = (src: string) => {
300+
const images = selectedMarker?.images || defaultImages;
301+
const index = images.indexOf(src);
302+
setCurrentImageIndex(index);
303+
setSelectedImage(src);
304+
};
305+
306+
const handlePrevImage = (e: React.MouseEvent) => {
307+
e.stopPropagation();
308+
const images = selectedMarker?.images || defaultImages;
309+
const newIndex = (currentImageIndex - 1 + images.length) % images.length;
310+
setCurrentImageIndex(newIndex);
311+
setSelectedImage(images[newIndex]);
312+
};
313+
314+
const handleNextImage = (e: React.MouseEvent) => {
315+
e.stopPropagation();
316+
const images = selectedMarker?.images || defaultImages;
317+
const newIndex = (currentImageIndex + 1) % images.length;
318+
setCurrentImageIndex(newIndex);
319+
setSelectedImage(images[newIndex]);
320+
};
321+
218322
return (
219323
<div style={{ width, height, position: 'relative' }}>
220324
{/* @ts-ignore - Using @ts-ignore to bypass type issues with react-map-gl */}
@@ -292,13 +396,40 @@ export function GlobeMap({
292396
<div className={classes.globeMapBounceCardsContainer}>
293397
<BounceCards
294398
className={classes.globeMapBounceCards}
295-
images={selectedMarker.images || defaultImages}
399+
images={getRandomImages(selectedMarker.images || defaultImages)}
296400
containerWidth={500}
297401
containerHeight={250}
298402
animationDelay={0.2}
299403
animationStagger={0.08}
300404
transformStyles={defaultTransformStyles}
301405
enableHover={true}
406+
onImageClick={handleImageClick}
407+
/>
408+
</div>
409+
)}
410+
411+
{/* Fullscreen Modal */}
412+
{selectedImage && (
413+
<div className={classes.modal} onClick={handleModalClick}>
414+
<div className={classes.closeButton} onClick={handleCloseClick}>
415+
×
416+
</div>
417+
<div
418+
className={`${classes.navButton} prev`}
419+
onClick={handlePrevImage}
420+
>
421+
422+
</div>
423+
<div
424+
className={`${classes.navButton} next`}
425+
onClick={handleNextImage}
426+
>
427+
428+
</div>
429+
<img
430+
className={classes.modalImage}
431+
src={selectedImage}
432+
alt="Fullscreen view"
302433
/>
303434
</div>
304435
)}

0 commit comments

Comments
 (0)