From b43e5ef54b22951601a9323e61d718b0f957c34b Mon Sep 17 00:00:00 2001 From: Sol25 Date: Thu, 12 Oct 2023 19:32:34 +0200 Subject: [PATCH] Gallery changes. Smooth scroll, small button changes, etc. --- .../Components/RoadDetails/ImageGallery.tsx | 86 ++++++++++++------- frontend/src/css/road_details.css | 51 ++++++++--- 2 files changed, 94 insertions(+), 43 deletions(-) diff --git a/frontend/src/Components/RoadDetails/ImageGallery.tsx b/frontend/src/Components/RoadDetails/ImageGallery.tsx index 53732eba..394f93ba 100644 --- a/frontend/src/Components/RoadDetails/ImageGallery.tsx +++ b/frontend/src/Components/RoadDetails/ImageGallery.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useRef, useEffect, useState } from 'react'; interface Image { id: number; @@ -70,28 +70,52 @@ const images: Image[] = [ const ImageGallery: React.FC = () => { const [scrollPosition, setScrollPosition] = useState(0); + const containerRef = useRef(null); + const [showArrows, setShowArrows] = useState(true); const openImageInNewTab = (imageUrl: string) => { window.open(imageUrl, '_blank'); }; const handleScroll = (scrollOffset: number) => { - const newScrollPosition = scrollPosition + scrollOffset; + if (!containerRef.current) return; - // Calculate the maximum scroll limit based on the total image width - const maxScrollLimit = (images.length - 11.4) * 124; // 120 is the width of each image + const containerWidth = containerRef.current.clientWidth; + const totalImageWidth = images.length * 124; // 120 for the image width and 4 for margin - // Ensure the scroll stays within bounds - const boundedScrollPosition = Math.max( - 0, - Math.min(newScrollPosition, maxScrollLimit), - ); + const centerOffset = (containerWidth - totalImageWidth) / 2; - setScrollPosition(boundedScrollPosition); + let newScrollPosition = scrollPosition + scrollOffset; + + // If scrolling to the left, don't go past half the container's width + if (scrollOffset < 0) { + newScrollPosition = Math.max(newScrollPosition, centerOffset); + } + // If scrolling to the right, don't go past the width of the images minus half the container's width + else { + newScrollPosition = Math.min( + newScrollPosition, + totalImageWidth - containerWidth + centerOffset, + ); + } + + setScrollPosition(newScrollPosition); }; + useEffect(() => { + if (containerRef.current) { + const containerWidth = containerRef.current.clientWidth; + const totalImageWidth = images.length * 124; + if (totalImageWidth <= containerWidth) { + setShowArrows(false); + } else { + setShowArrows(true); + } + } + }, []); + return ( -
+
{ ))}
- - + {showArrows && ( + <> + + + + )}
); }; diff --git a/frontend/src/css/road_details.css b/frontend/src/css/road_details.css index cd96b9f9..5eaffc7d 100644 --- a/frontend/src/css/road_details.css +++ b/frontend/src/css/road_details.css @@ -1,6 +1,3 @@ -/* src/styles.css */ - -/* Define styles for the top bar */ .top-bar { background-color: #333; /* Example color for the top bar */ height: 50px; @@ -170,22 +167,32 @@ input[type='checkbox'] { } .image-gallery-container { - display: flex; /* Add display: flex */ - flex-direction: column; /* Stack children vertically */ - justify-content: center; /* Center children vertically */ + display: flex; + justify-content: center; + align-items: center; position: relative; + overflow: hidden; + width: 100%; + padding-left: 15px; + padding-left: 15px; + padding-right: 15px; } .image-gallery-page { display: flex; - overflow-x: auto; /* Enable horizontal scrolling */ - max-width: 100%; /* Set a maximum width */ + justify-content: center; + align-items: center; + overflow-x: scroll; + padding-left: 15px; + padding-right: 15px; } .image-container { display: flex; - align-items: center; - margin-left: 0.5vh; + justify-content: center; /* This will center the images */ + flex-wrap: nowrap; /* This will prevent images from wrapping to the next line */ + transition: transform 0.3s ease; + overflow-y: hidden; /*Added this to stop vertical scroll rect to appear when hovering over images - SL*/ } .image-thumbnail { @@ -194,19 +201,24 @@ input[type='checkbox'] { object-fit: cover; /* Preserve aspect ratio and cover the container */ cursor: pointer; transition: transform 0.3s ease-in-out; - margin-right: 4px; + margin-right: 2px; margin-top: 0.5vh; text-align: center; + margin-left: 2px; + flex-shrink: 0; + display: inline-block; } .arrow-button { - background-color: #fff; + background-color: rgba(255, 255, 255, 0.8); border: none; height: 50px; width: 50px; + top: 30%; border-radius: 50%; position: absolute; box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2); + box-sizing: border-box; cursor: pointer; display: flex; align-items: center; @@ -216,10 +228,21 @@ input[type='checkbox'] { } .left-arrow { - left: 10px; + left: 50px; transform: rotate(180deg); + transform: translateY(-50%) rotate(180deg); } .right-arrow { - right: 10px; + right: 50px; + transform: translateY(-50%); +} + +.arrow-button.disabled { + opacity: 0; + pointer-events: none; +} + +.image-thumbnail:first-child { + margin-left: 0; }