Ayush Srivastava
Ayush Srivastava

Reputation: 304

How to get a particular div into fullscreen(full window size) in reactjs

I am making a Image viewer in ReactJs as I am newbie in this so I stuck at a point. actually I have to add a full screen option. when user click on any particular image the image is open and there is a option like next,prev,close,rotate and fullscreen(that is takes height and width of browser) so when user click on full screen that particular image will get the full window size and user still have option like rotate,next.close and prev. I searched for so many solution but nothing worked.

I tried so many things but it only does the fullscreen whole body but I want .center-image to be full screen with options as I said. This is the gallary modal component.

class GalleryModal extends React.Component {
        constructor(props) {
          super(props);

          this.state = {
            rotation: 0
          };
          this.rotate = this.rotate.bind(this);
        }

        render() {
          const { rotation } = this.state;
          if (this.props.isOpen === false) {
            return null;
          }

          return (
            <div className="modal-overlay" name={this.props.name}>
              <div className="modal-body">
                <a href="#" className="button" onClick={() => this.rotate()}>
                  <i className="fas fa-sync-alt" />
                </a>
                <a href="#" className="button" onClick={this.props.onPrev}>
                  <i className="fas fa-angle-left" />
                </a>
                <img
                  className="center_image"
                  id="image"
                  src={this.props.src}
                  style={{ transform: `rotate(${rotation}deg)` }}
                />
                <a href="#" className="button" onClick={this.props.onNext}>
                  <i className="fas fa-angle-right" />
                </a>
                <a
                  className="modal-close"
                  href="#"
                  onClick={this.props.onClick}
                >
                  <span className="fa fa-times" />
                </a>
              </div>
            </div>
          );
        }
        rotate() {
          let newRotation = this.state.rotation + 90;
          if (newRotation >= 360) {
            newRotation = -360;
          }
          this.setState({
            rotation: newRotation
          });
        }
      }

Full code

This is my code and I am confused how to add the fullscreen option and where to add it .

Upvotes: 2

Views: 11594

Answers (3)

Oded Ben Dov
Oded Ben Dov

Reputation: 10397

Found this library which does exactly what you describe:

https://www.npmjs.com/package/react-fullscreen-image

You can use as is or look into the code for guidance

Upvotes: 0

Matt Carlotta
Matt Carlotta

Reputation: 19762

Had to use some css tricks, but I believe this is what you're looking to achieve. The image is centered and takes up the maximum amount of width that is available within the window; however, if you stretch the window, it'll adjust its width up until it hits its max width (not advised to stretch it beyond its max value, otherwise, you'll get pixelation).

I did simplify your code a bit by elevating state and class methods to a single container, as well as, used setState() callbacks to manage state more efficiently and the ternary operator (cond ? true : false) in replace of simple if/else conditional statements.

Working example: https://codesandbox.io/s/zr5k7v0zp3

containers/Gallery/Gallery.js

import React from "react";
import GalleryImages from "../../components/GalleryImages/galleryImages";
import GalleryModal from "../../components/GalleryModal/galleryModal";

const imgUrls = [
  "https://source.unsplash.com/3Z70SDuYs5g/800x600",
  "https://source.unsplash.com/01vFmYAOqQ0/800x600",
  "https://source.unsplash.com/2Bjq3A7rGn4/800x600",
  "https://source.unsplash.com/t20pc32VbrU/800x600",
  "https://source.unsplash.com/pHANr-CpbYM/800x600",
  "https://source.unsplash.com/3PmwYw2uErY/800x600",
  "https://source.unsplash.com/uOi3lg8fGl4/800x600",
  "https://source.unsplash.com/CwkiN6_qpDI/800x600",
  "https://source.unsplash.com/9O1oQ9SzQZQ/800x600",
  "https://source.unsplash.com/E4944K_4SvI/800x600",
  "https://source.unsplash.com/-hI5dX2ObAs/800x600",
  "https://source.unsplash.com/vZlTg_McCDo/800x600"
];

export default class Gallery extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      imgIndex: 0,
      imgUrlLength: imgUrls.length,
      showModal: false,
      rotation: 0
    };

    this.openModal = this.openModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
    this.nextClick = this.nextClick.bind(this);
    this.prevClick = this.prevClick.bind(this);
    this.rotateImage = this.rotateImage.bind(this);
  }

  openModal(index) {
    this.setState({
      showModal: true,
      imgIndex: index
    });
  }

  closeModal() {
    this.setState({
      showModal: false,
      imgIndex: 0,
      rotation: 0
    });
  }

  nextClick() {
    this.setState(prevState => {
      return {
        imgIndex:
          prevState.imgIndex === prevState.imgUrlLength - 1
            ? 0
            : prevState.imgIndex + 1
      };
    });
  }

  prevClick() {
    this.setState(prevState => {
      return {
        imgIndex:
          prevState.imgIndex === 0
            ? prevState.imgUrlLength - 1
            : prevState.imgIndex - 1
      };
    });
  }

  rotateImage() {
    this.setState(prevState => {
      return {
        rotation: prevState.rotation + 90 <= 270 ? prevState.rotation + 90 : 0
      };
    });
  }

  render() {
    return (
      <div className="container-fluid gallery-container">
        <GalleryImages imgUrls={imgUrls} openModal={this.openModal} />
        <GalleryModal
          isOpen={this.state.showModal}
          onClick={this.closeModal}
          onNext={this.nextClick}
          onPrev={this.prevClick}
          rotateImage={this.rotateImage}
          rotation={this.state.rotation}
          src={imgUrls[this.state.imgIndex]}
        />
      </div>
    );
  }
}

components/GalleryImages/galleryImages.js

import React from "react";
import PropTypes from "prop-types";

const GalleryImages = ({ imgUrls, openModal }) => {
  return (
    <div className="row">
      {imgUrls.map((url, index) => {
        return (
          <div key={index} className="col-sm-6 col-md-3 col-xl-2">
            <div className="gallery-card">
              <img
                key={index}
                className="gallery-thumbnail"
                src={url}
                alt={`Image number ${index + 1}`}
              />

              <span
                className="card-icon-open fa fa-expand"
                onClick={() => openModal(index)}
              />
            </div>
          </div>
        );
      })}
    </div>
  );
};

GalleryImages.propTypes = {
  imgUrls: PropTypes.arrayOf(PropTypes.string).isRequired,
  openModal: PropTypes.func.isRequired
};

export default GalleryImages;

components/GalleryModal/galleryModal.js

import React from "react";
import PropTypes from "prop-types";

const GalleryModal = ({
  isOpen,
  onClick,
  onNext,
  onPrev,
  rotateImage,
  rotation,
  src
}) => {
  return isOpen ? (
    <div className="modal-overlay">
      <div className="modal-body">
        <div className="close-modal">
          <a className="modal-close" href="#" onClick={onClick}>
            <span className="fa fa-times" />
          </a>
        </div>
        <div className="rotate-container">
          <a href="#" className="button" onClick={rotateImage}>
            <i style={{ fontSize: 44 }} className="fas fa-sync-alt" />
          </a>
        </div>
        <div className="image-container">
          <div>
            <a href="#" className="button" onClick={onPrev}>
              <i className="fas fa-angle-left" />
            </a>
          </div>
          <div>
            <img
              src={src}
              style={{ transform: `rotate(${rotation}deg)`, width: "100%" }}
            />
          </div>
          <div>
            <a href="#" className="button" onClick={onNext}>
              <i className="fas fa-angle-right" />
            </a>
          </div>
        </div>
      </div>
    </div>
  ) : null;
};

GalleryModal.propTypes = {
  isOpen: PropTypes.bool.isRequired,
  onClick: PropTypes.func.isRequired,
  onNext: PropTypes.func.isRequired,
  onPrev: PropTypes.func.isRequired,
  rotateImage: PropTypes.func.isRequired,
  rotation: PropTypes.number.isRequired,
  src: PropTypes.string
};

export default GalleryModal;

styles.css

html,
body {
  min-height: 100%;
  height: 100%;
}
html {
  font-size: 16px;
}
body {
  position: relative;
  font-size: 100%;
}
.button {
  font-size: 50px;
  color: #eee;
  margin: 5px;
}
.card-icon-open {
  display: block;
  position: relative;
  left: 45%;
  top: 35px;
  font-size: 30px;
  width: 30px;
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transform: translate(0%, -400%);
  transition: all 0.25s ease-in-out;
}
.card-icon-open:focus,
.card-icon-open:hover {
  color: #111;
}
.close-modal {
  position: fixed;
  top: 0;
  right: 5px;
}
.fullscreen {
  position: relative;
  text-decoration: none;
  font-size: 25px;
  color: #eee;
  z-index: 999;
}
.fullscreen:hover,
.fullscreen:focus,
.fullscreen:blur {
  text-decoration: none;
  color: red;
}
.gallery-container {
  padding-top: 10px;
}
.gallery-card {
  position: relative;
  overflow: hidden;
  margin-bottom: 10px;
}
.gallery-thumbnail {
  max-width: 100%;
  height: auto;
  border-radius: 4px;
}
.gallery-thumbnail:focus ~ .card-icon-open,
.gallery-thumbnail:hover ~ .card-icon-open,
.gallery-thumbnail ~ .card-icon-open:focus,
.gallery-thumbnail ~ .card-icon-open:hover {
  opacity: 1;
}
.image-container {
  display: flex;
  justify-content: center;
  align-items: center;
}
.image-rotate {
  font-size: 44px;
}
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  width: 100%;
  height: 100%;
  background: rgba(21, 21, 21, 0.75);
}
.modal-body {
  position: relative;
  top: 15%;
  z-index: 11;
  padding: 0;
  overflow: hidden;
  max-width: 100%;
  max-height: 100%;
}
.modal-close {
  font-size: 44px;
  z-index: 99;
  color: #eee;
  transition: all 0.25s ease-in-out;
}
.modal-close:focus,
.modal-close:hover {
  color: red;
}
.rotate-container {
  font-size: 44px;
  position: fixed;
  top: 0;
  left: 5px;
}

Upvotes: 1

Josh Pittman
Josh Pittman

Reputation: 7324

I recommend using css viewport units, setting a component to height: 100vh and width: 100vw will make it fullscreen. You then conditionally render the component based on when you want it to be fullscreen.

Upvotes: 4

Related Questions