2

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 .

Ayush Srivastava
  • 284
  • 3
  • 5
  • 17

3 Answers3

4

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.

Josh Pittman
  • 7,024
  • 7
  • 38
  • 66
  • Basically I want the image `.center_image` to take full window size on click of that button .plz see this fiddle http://jsfiddle.net/ayush88089/f1pg4k7r/3/ .... I stucked on it over a month so plz help . – Ayush Srivastava Feb 18 '19 at 07:19
  • 1
    Josh literally just gave you the solution to your problem @AyushSrivastava – Jasper Lichte Feb 18 '19 at 07:27
  • I m really sorry @JasperLichte as I don't very much about reactJS I am beginner I understand that if I give any element 100vh and 100vw it will take full screen (not window size) But I am stuck that how can I manage to get that particular div full browser height and width? – Ayush Srivastava Feb 18 '19 at 07:37
  • @AyushSrivastava I kinda fail to understand your question. Just add a className/id to your desired div and size it in your css file. Alternatively, assign a `style` prop to your div. Just like you'd do in vanilla JS really – Jasper Lichte Feb 18 '19 at 07:43
  • @JasperLichte I tried myself what I understand from these answer all thing is going well but a error occurs like when I click on any image and rotate it and close it and after that if I opens other it takes the previous rotation value but it must be zero.This error is arrising after I edited all my code. see jsfiddle.net/ayush88089/r0h7gv62/1 This is what I tried when you click on full screen icon it will fullscreen the image . But I doesn't know from where the rotation error is arrised can you please tell me what I am doing wrong???? – Ayush Srivastava Feb 18 '19 at 09:44
  • 1
    Now you are asking a completely different question. Please accept my answer if it was helpful and then open a new question for your new problem. Keeping one question about one problem helps other people with your original problem find this thread. – Josh Pittman Feb 18 '19 at 09:48
  • @JoshPittman can u please look at this question https://stackoverflow.com/questions/54746698/variable-is-not-taking-the-initial-value-of-a-variable-in-reactjs – Ayush Srivastava Feb 18 '19 at 12:04
1

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;
}
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
  • Actually before seeing your solution I tried myself all thing is going well but a error occurs like when I click on any image and rotate it and close it and after that if I opens other it takes the previous `rotation` value but it must be zero. https://jsfiddle.net/ayush88089/r0h7gv62/1/ This is what I tried when you click on full screen icon it will fullscreen the image . But I doesn't know from where the rotation error is arrised can you please tell me what I am doing wrong???? @MattCarlotta – Ayush Srivastava Feb 18 '19 at 09:38
0

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

Oded Ben Dov
  • 9,936
  • 6
  • 38
  • 53