简体   繁体   English

根据图像文件的实际高度和宽度(React)为图像动态跨越网格行和列

[英]Span grid rows and columns dynamically for an image based on the image file actual height and width ( React )

I have a specific requirement which is to dynamically determine the number of rows & columns needed to be spanned based on image height.我有一个特定的要求,即根据图像高度动态确定需要跨越的行数和列数。 I have tried couple of ways, latest one of them is at the end of the question.我尝试了几种方法,其中最新的一种是在问题的末尾。

Here is the current code that needs suggestions这是需要建议的当前代码

HTML HTML

<div className="grid">
    {
     pictures.map((pic,i)=>{
      return(
        <div key={pic.name+i} className="pic-container" 
         style={{ 
             gridRowStart: pic.row, gridColumnStart:pic.col, 
             // Need to put the height & width of each image in the array 
             // in the following place to span dynamically
             gridRowEnd: HEIGHT/50 , gridColumnEnd:8*(WIDTH/1400)}}>
         <div>
            <img src={`/pictures/${pic.name}.png`} className="pic"/>
            <div className="pic-name">{pic.name}</div>
         </div>
        </div>
      );
    }
</div>

CSS CSS

.grid{
  display: grid;
  grid-template-rows: repeat(99, 50px);
  grid-template-columns: repeat(8, 1fr);
  max-width: 1400px;
  gap: 0px;
  position: relative;
  z-index: 2;
}
.pic-container{
  width: 100%;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pic-container > div{
  display: block;
  width:100%;
  height:100%;
}

.pic{
  max-width: 100%;
  max-height: 100%;
  height: 100%;
  object-fit: contain;
}

Latest that I have tried:我尝试过的最新产品:

const [width,setWidth] = useState(null);
const [height,setHeight] = useState(null);
.
..
...
pictures.map((pic,i)=>{
  const getDim = (e) =>{
    setWidth(e.target.offsetWidth);
    setHeight(e.target.offsetHeight);
  }
  return(
    <div key={''+pic.name+i} className="pic-container" 
     style={{gridArea:`${pic.row} / ${pic.col} / span ${Math.ceil(height/50)} / span ${Math.ceil(8*(width/1400))`}}>
      <div>
        <img onLoad={getDim} className="pic" src={`/pictures/${pic.name}.png`}/>
        <div className="pic-name">{pic.name}</div>
      </div>
    </div>
  )
})

The idea behind the previous solution is that everytime we get a new image the state of width and height will get updated with the new image dimensions and then will be applied on the span.先前解决方案背后的想法是,每次我们获得新图像时,宽度和高度的 state 都会使用新的图像尺寸进行更新,然后将应用于跨度。 Next image will update the width and height and then have them applied on its span and so on so forth.下一个图像将更新宽度和高度,然后将它们应用于其跨度等等。 But that didn't work.但这没有用。

I hope this maybe help you.我希望这可能对你有所帮助。

Sandbox demo here 沙盒演示在这里

Image List Component:图像列表组件:

    const ImageList = (props) => {
    
    const images = props.images.map((image) => {
        return <ImageCard key={image.id} image={image} />
    });
   return <div className="image-list">{images}</div>

Image List Css图像列表 Css

.image-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    grid-gap:0 10px;
    grid-auto-rows: 10px;
}

.image-list img {
    width: 250px;
 }

ImageCard component:图像卡组件:

class ImageCard extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            spans : 0
        }
        this.imageRef = React.createRef();
    }    

    componentDidMount() {
         this.imageRef.current.addEventListener('load', this.setSpans);

    }

    setSpans = () => {
        const height = this.imageRef.current.clientHeight;

        const spans = Math.ceil(height / 10);

        this.setState({spans});
    }

    render() {
        const {description, urls} = this.props.image;
        return (
            <div style={{gridRowEnd: `span ${this.state.spans}`}}>
                <img ref={this.imageRef} src={urls.regular} alt={description} />
            </div>
        );
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM