Skip to content

Instantly share code, notes, and snippets.

@mohandere
Last active January 28, 2021 09:24
Show Gist options
  • Save mohandere/a6edde861467dc8bd8c45d553f1c50a4 to your computer and use it in GitHub Desktop.
Save mohandere/a6edde861467dc8bd8c45d553f1c50a4 to your computer and use it in GitHub Desktop.
React js Responsive Gallery with Masonry Layout and Lightbox
import React, {
Component
} from 'react';
//Import responsive gallery component
import ResponseiveGallery from './components/ResponsiveGallery';
// Define array of images with thumbnails
const DEFAULT_IMAGES = [{
src: '/images/gallery-1.jpg',
thumbnail: '/images/gallery-1.jpg',
caption: 'Image 1',
}, {
src: '/images/gallery-2.jpg',
thumbnail: '/images/gallery-2.jpg',
caption: 'Image 2',
}, {
src: '/images/gallery-3.jpg',
thumbnail: '/images/gallery-3.jpg',
caption: 'Image 3',
}, {
src: '/images/gallery-4.jpg',
thumbnail: '/images/gallery-4.jpg',
caption: 'Image 4',
}, {
src: '/images/gallery-5.jpg',
thumbnail: '/images/gallery-5.jpg',
caption: 'Image 5',
}];
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<ResponseiveGallery images={DEFAULT_IMAGES.map(({ src, thumbnail, caption }) => ({
src,
thumbnail,
caption,
}))} />
)
}
}
import React, {
Component
} from 'react';
import Lightbox from 'react-images';
import PropTypes from 'prop-types';
import Masonry from 'react-masonry-component';
const masonryOptions = {
transitionDuration: 0,
gutter: 10,
percentPosition: true,
columnWidth: 300,
};
export default class ResponsiveGallery extends Component {
constructor(props) {
super(props);
this.state = {
lightboxIsOpen: false,
currentImage: 0,
};
this.closeLightbox = this.closeLightbox.bind(this);
this.gotoNext = this.gotoNext.bind(this);
this.gotoPrevious = this.gotoPrevious.bind(this);
this.gotoImage = this.gotoImage.bind(this);
this.handleClickImage = this.handleClickImage.bind(this);
this.openLightbox = this.openLightbox.bind(this);
}
openLightbox(index, event) {
event.preventDefault();
this.setState({
currentImage: index,
lightboxIsOpen: true,
});
}
closeLightbox() {
this.setState({
currentImage: 0,
lightboxIsOpen: false,
});
}
gotoPrevious() {
this.setState({
currentImage: this.state.currentImage - 1,
});
}
gotoNext() {
this.setState({
currentImage: this.state.currentImage + 1,
});
}
gotoImage(index) {
this.setState({
currentImage: index,
});
}
handleClickImage() {
if (this.state.currentImage === this.props.images.length - 1) return;
this.gotoNext();
}
renderGallery() {
const {
images
} = this.props;
if (!images) return;
const gallery = images.map((obj, i) => {
return (
<div key={i} className={`grid-item`}>
<img onClick={(e) => this.openLightbox(i, e)} src={obj.thumbnail} className={`gallery-img`}/>
</div>
);
});
return (
<Masonry
className={'grid'} // default ''
options={masonryOptions}
disableImagesLoaded={false}
updateOnEachImageLoad={true}>
{gallery}
</Masonry>
);
}
render() {
return (
<div className={`content container`}>
<h4>Gallery</h4>
{this.renderGallery()}
<Lightbox
currentImage={this.state.currentImage}
images={this.props.images}
isOpen={this.state.lightboxIsOpen}
onClickImage={this.handleClickImage}
onClickNext={this.gotoNext}
onClickPrev={this.gotoPrevious}
onClickThumbnail={this.gotoImage}
onClose={this.closeLightbox}
showThumbnails={this.props.showThumbnails}
theme={this.props.theme} />
</div>
);
}
}
ResponsiveGallery.propTypes = {
images: PropTypes.array,
showThumbnails: PropTypes.bool,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment