如何在 reactjs 中将特定 div 变为全屏(完整 window 大小)

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

我在 ReactJs 中制作一个图像查看器,因为我是这方面的新手,所以我卡在了一个点上。实际上我必须添加一个全屏选项。当用户单击任何特定图像时,图像会打开,并且有一个选项,如下一个、上一个、关闭、旋转和全屏(即采用浏览器的高度和宽度),因此当用户单击全屏时,该特定图像将获得全屏window 大小和用户仍然可以选择旋转,next.close 和上一个。我搜索了很多解决方案,但没有任何效果。

我尝试了很多东西,但它只能全屏显示 body 但我希望 .center-image 像我说的那样全屏显示选项。这是画廊模态组件。

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

这是我的代码,我对如何添加全屏选项以及在哪里添加感到困惑。

我建议使用 css 视口单位,将组件设置为高度:100vh 和宽度:100vw 将使其全屏显示。然后,您可以根据希望全屏显示的时间有条件地渲染组件。

不得不使用一些 css 技巧,但我相信这就是您想要实现的目标。图像居中并占据 window 范围内可用的最大宽度;然而,如果你拉伸 window,它会调整它的宽度直到它达到它的最大宽度(不建议拉伸它超过它的最大值,否则,你会得到像素化)。

我通过将 state 和 class methods 提升为单个 container 以及使用 setState() callbacks to manage state more efficiently and the ternary operator (cond ? true : false) 替换简单的 if/else 条件语句。

工作示例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;
}

发现这个库完全符合您的描述:

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

您可以按原样使用或查看代码以获取指导