Issue
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.
Can someone help me if I'm on the right path or there is a better way to do this?
Solution
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>
Answered By - Pranav Rustagi
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.