skip to Main Content

I’m trying to create a lightbox,

I have a thumbnail carousel at the bottom of the images that you click on to change the displayed image. I want to make it so that when you click on any thumbnail, it scrolls to the center of the page making it seem like the selected element remains constantly at the center of the screen.

What I’ve done till now is I’ve added a dynamic left padding to the ThumbnailViewer container.

const ThumbnailViewer = (props) => {
const {
    images = [],
    currentImage = 0,
    thumbnailWidth
} = useContext(LightboxContext);

const getThumbnailViewerPaddingLeft = () => {
    if (thumbnailWidth) {
        return `calc(95vw - ${(thumbnailWidth * (currentImage + 1))}px)`
    }

}
const getThumbnailViewerPaddingRight = () => {
    if (thumbnailWidth) {
        return `calc(95vw - ${thumbnailWidth}px)`
    }

}

return (
    <div className={styles.thumbnailViewer} style={{ paddingLeft: getThumbnailViewerPaddingLeft() }}>
        {images.map((el, i) => <ThumbnailIcon img={el.src} alt={el.alt} selected={i == currentImage} current={i} />)}
    </div>
)

}

I’m unable to get it centred as you can see in this gif below and I’m not sure if this approach is right. I’m thinking to dynamically reduce left padding and then add right padding to it constantly so that when clicking on the right most element it gets to the center too.

enter image description here

Can someone help me if I’m on the right path or there is a better way to do this?

2

Answers


  1. Relying on thumbnail width and adjusting padding might not be the most effective method. A more efficient approach involves utilizing the array index of the images. When a user clicks on a thumbnail, you can reposition that thumbnail to the middle of the array. This way, if you want the user to always stay centered upon clicking either left or right thumbnails, you can simply modify the array accordingly. This method offers a more dynamic and responsive user experience

    Login or Signup to reply.
  2. Best way to achieve this would be to have a layout like this and update transform property on every click.

    Doing so would be efficient because component will not have to re-render. You can use refs to update DOM. Checkout (refs and forwardRefs).

    const imgCnt = document.querySelector(".imgcnt");
    const thumbsCnt = document.querySelector(".thumbs");
    const thumbs = document.querySelectorAll(".thumb");
    thumbs.forEach((thumb, index) => {
      thumb.addEventListener("click", () => {
        imgCnt.children[0].src = thumb.src;
        thumbsCnt.style.transform = `translateX(calc(50% - (${index} * (10vh + 10px)) - 5vh))`;
      });
    });
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
      overflow-x: hidden;
    }
    
    .main {
      height: 100vh;
      display: flex;
      flex-direction: column;
      padding: 5vh 5vw;
      align-items: center;
      background: beige;
      gap: 5vh;
    }
    
    .imgcnt {
      display: flex;
      justify-content: center;
      height: 70vh;
      width: 100%;
    }
    
    .imgcnt img {
      height: 100%;
    }
    
    .thumbs {
      height: 15vh;
      transform: translateX(calc(50% - 5vh));
      display: flex;
      gap: 10px;
    }
    
    .thumb {
      background: teal;
      width: 10vh;
      height: 100%;
      object-fit: fill;
    }
    <div class="main">
      <div class="imgcnt">
         <img src="https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg?auto=compress&cs=tinysrgb&w=600" />
      </div>
      <div class="thumbs">
        <img class="thumb" src="https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1386604/pexels-photo-1386604.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/757889/pexels-photo-757889.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1181181/pexels-photo-1181181.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/919278/pexels-photo-919278.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1386604/pexels-photo-1386604.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1321909/pexels-photo-1321909.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1181181/pexels-photo-1181181.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/674010/pexels-photo-674010.jpeg?auto=compress&cs=tinysrgb&w=600" />
        <img class="thumb" src="https://images.pexels.com/photos/1366630/pexels-photo-1366630.jpeg?auto=compress&cs=tinysrgb&w=600" />
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search