当前位置: 首页 > 知识库问答 >
问题:

在一个图像网格和一个图像滑块之间切换,其中一个图像数组位于react钩子中

宓和同
2023-03-14

我正在用Nextjs、React和使用Sanity作为CMS构建一个项目。

其中一个主要组件将是一个图像库,当你点击这些图像时,你将打开一个图像滑块库。图像是从CMS传入的数组。

它松散地建立在这个网站的工作方式上。https://www.garrodkirkwood.com/projects/

目前,我正在使用一个简单的setState切换来隐藏和显示图像库和幻灯片。代码远不是完美的,因为我意识到有很多事情要做。

我需要的是...

我需要找到一种方法来将点击图像的索引传递给事件监听器,这样当您点击图像时,就可以打开同一图像上的幻灯片。

我真的希望这有意义。

然后,用户将通过单击“显示缩略图”退出幻灯片放映。

import React, { useState, useEffect, useRef } from "react";
import { css, jsx } from "@emotion/core";
import ImageSliderContent from "./ImageSliderContent";
import styles from "./ImageGrid.module.css";
import ImageGrid from "./ImageGrid";
import ImageSlide from "./ImageSlide";
import Arrow from "./Arrow";
import Dots from "./Dots";
import imageUrlBuilder from "@sanity/image-url";
import client from "../../client";

const builder = imageUrlBuilder(client);

const LocationsImageGallery = (props) => {
  const { caption, image } = props;

  const images = props.image;

  const [state, setState] = useState({
    translate: 0,
    transition: 0.45,
    activeSlide: 0,
  });

  const [showSlider, setShowSlider] = useState(false);

  const { translate, transition, activeSlide, _slides } = state;

  const size = useWindowSize();
  const transitionRef = useRef();

  function useWindowSize() {
    const isClient = typeof window === "object";

    function getSize() {
      return {
        width: isClient ? window.innerWidth : undefined,
      };
    }

    const [windowSize, setWindowSize] = useState(getSize);

    useEffect(() => {
      if (!isClient) {
        return false;
      }

      function handleResize() {
        setWindowSize(getSize());
      }

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

    return windowSize;
  }

  const nextSlide = () => {
    if (activeSlide === images.length - 1) {
      return setState({
        ...state,
        translate: 0,
        activeSlide: 0,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide + 1,
      translate: (activeSlide + 1) * size.width,
    });
  };

  const prevSlide = () => {
    if (activeSlide === 0) {
      return setState({
        ...state,
        translate: (images.length - 1) * size.width,
        activeSlide: images.length - 1,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide - 1,
      translate: (activeSlide - 1) * size.width,
    });
  };

  const show = () => {
    setShowSlider(true);
  };

  const hide = () => {
    setShowSlider(false);
  };

  return (
    <div className={styles.root}>
      <div className={styles.imageGridContainer}>
        {images.map((image, index) => (
          <div className={styles.imageContainer} onClick={show}>
            <img
              src={builder.image(image).auto("format").width(2000).url()}
              className={styles.image}
              alt={image.caption}
              key={index}
            />
            <p className={styles.caption}>{image.caption}</p>
          </div>
        ))}
      </div>

      {showSlider && (
        <div className={styles.imageGalleryContainer}>
          <div css={ImageSliderCSS}>
            <ImageSliderContent
              translate={translate}
              transition={transition}
              width={size.width * images.length}
            >
              {images.map((image, index) => (
                <ImageSlide
                  key={image + index}
                  content={builder.image(image).auto("format").width(2000).url()}
                ></ImageSlide>
              ))}
            </ImageSliderContent>
            <Arrow direction="left" handleClick={prevSlide} />
            <Arrow direction="right" handleClick={nextSlide} />
            <Dots slides={images} activeSlide={activeSlide} />
          </div>
          <a href="" onClick={hide}>
            Show Thumbnails
          </a>
        </div>
      )}
    </div>
  );
};

const ImageSliderCSS = css`
  position: relative;
  height: 500px;
  width: 750px;
  margin: 0 auto;
  overflow: hidden;
`;
export default LocationsImageGallery;

通过将索引传递给CLICK事件更新

import React, { useState, useEffect, useRef } from "react";
import { css, jsx } from "@emotion/core";
import ImageSliderContent from "./ImageSliderContent";
import styles from "./LocationsImageGallery.module.css";
import ImageGrid from "./ImageGrid";
import ImageSlide from "./ImageSlide";
import Arrow from "./Arrow";
import Dots from "./Dots";
import imageUrlBuilder from "@sanity/image-url";
import client from "../../client";

const builder = imageUrlBuilder(client);

const LocationsImageGallery = (props) => {
  const { caption, image } = props;

  const images = props.image;

  const [state, setState] = useState({
    translate: 0,
    transition: 0.45,
    activeSlide: 0,
  });

  const [showSlider, setShowSlider] = useState(false);
  const [showGrid, setShowGrid] = useState(true);

  const { translate, transition, activeSlide, _slides } = state;

  const size = useWindowSize();
  const transitionRef = useRef();

  function useWindowSize() {
    const isClient = typeof window === "object";

    function getSize() {
      return {
        width: isClient ? window.innerWidth : undefined,
      };
    }

    const [windowSize, setWindowSize] = useState(getSize);

    useEffect(() => {
      if (!isClient) {
        return false;
      }

      function handleResize() {
        setWindowSize(getSize());
      }

      window.addEventListener("resize", handleResize);
      return () => window.removeEventListener("resize", handleResize);
    }, []);

    return windowSize;
  }

  const nextSlide = () => {
    if (activeSlide === images.length - 1) {
      return setState({
        ...state,
        translate: 0,
        activeSlide: 0,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide + 1,
      translate: (activeSlide + 1) * size.width,
    });
  };

  const prevSlide = () => {
    if (activeSlide === 0) {
      return setState({
        ...state,
        translate: (images.length - 1) * size.width,
        activeSlide: images.length - 1,
      });
    }

    setState({
      ...state,
      activeSlide: activeSlide - 1,
      translate: (activeSlide - 1) * size.width,
    });
  };

  const show = (index) => {
    setShowGrid(false);
    setShowSlider(true);
    setState({ activeSlide: index });
  };

  const hide = () => {
    setShowSlider(false);
    setShowGrid(true);
  };

  return (
    <div className={styles.root}>
      <div className={styles.header}>
        <a href="/locations">X</a>
      </div>
      {showGrid && (
        <div className={styles.imageGrid}>
          <div className={styles.imageGridContainer}>
            {images.map((image, index, caption) => (
              <div className={styles.imageContainer} onClick={() => show(index)}>
                <img
                  src={builder.image(image).auto("format").width(2000).url()}
                  className={styles.image}
                  alt={image.caption}
                  key={index}
                />
                <p className={styles.caption}>{image.caption}</p>
              </div>
            ))}
          </div>
        </div>
      )}

      {showSlider && (
        <div className={styles.imageGalleryContainer}>
          <div className={styles.imageSlider}>
            <ImageSliderContent
              translate={translate}
              transition={transition}
              width={size.width * images.length}
            >
              {images.map((image, index, caption) => (
                <>
                  <ImageSlide
                    key={image + index}
                    content={builder.image(image).auto("format").url()}
                  ></ImageSlide>
                </>
              ))}
            </ImageSliderContent>
            <Arrow direction="left" handleClick={prevSlide} />
            <Arrow direction="right" handleClick={nextSlide} />
          </div>
          <div className={styles.infoBar}>
            <p className={styles.infoCaption}>
              Locations / <span>{image.caption}</span>
            </p>
            <a href="" onClick={hide} className={styles.infoThumbnails}>
              Show Thumbnails
            </a>
          </div>
        </div>
      )}
    </div>
  );
};

export default LocationsImageGallery;

这个版本,似乎没有更新activeSlide的状态、console.log和状态...

LocationsImageGallery.js?0692:94{ActiveSlide:8,State:{…}}ActiveSlide:8 State:ActiveSlide:0 Transition:0.45 Translate:0 Proto:Object Proto:Object

共有1个答案

越胤
2023-03-14

您可以更改show函数以将幻灯片索引作为参数:

  const show = (index) => {
    // set activeSlide accordingly
    setState(...)
    setShowSlider(true);
  }

然后,在onClick函数中,传入索引:

onClick={() => show(index)}

如果我是您,我可能会删除showslider状态,并使用activeslide:-1activeslide:null表示不显示滑块。

 类似资料:
  • 问题内容: 我是Rails编程的初学者,试图在页面上显示许多图像。有些图像要放在其他图像之上。为简单起见,假设我要一个蓝色正方形,在蓝色正方形的右上角有一个红色正方形(但在角落不紧)。由于性能问题,我试图避免进行合成(使用ImageMagick等)。 我只想相对于彼此放置重叠的图像。 举一个更困难的例子,想象一下将里程表放在更大的图像中。对于六位数字,我将需要合成一百万个不同的图像,或者即时进行处

  • 问题内容: 我正在学习Swift,并且正在创建一个使用个人照片的应用程序,并将另一个放在上面。我现在有一个hacky解决方案,可以创建该区域的屏幕截图并保存。我需要在Swift中执行此操作 但是,这是可行的,现在不再可行。但是,这也不是最佳解决方案。 那么,伙计们,我该如何将个人图像中的图像作为叠加图像保存到相机胶卷中? 帮助将不胜感激!谢谢! 问题答案: 我建议阅读此线程。您所有的答案都在那里。

  • 如何替换PDF中的图像与另一个图像PDF框。怎么做? 我想用另一个图像更改pdf上的VisualSignature。

  • 问题内容: 我正在尝试从Matplotlib图中获取一个numpy数组图像,目前正在通过保存到文件中,然后再读回文件的方式来完成此操作,但是我觉得必须有一种更好的方法。这是我现在正在做的事情: 我尝试了这个: 从我发现的示例中发现,但是它给我一个错误,指出“ FigureCanvasAgg”对象没有属性“ renderer”。 问题答案: 为了获得图形内容作为RGB像素值,需要首先绘制画布的内容。

  • 我需要帮助来识别边界,并将图像与原始图像进行比较。我需要指导如何我可以实现这通过处理或matlab或任何初学者。例如,请看下面的图像。 原始图像:

  • 我目前有一个游戏,有一个地图是480x3200,一个人从顶部掉下来。镜头跟在人的后面,随着人的下落有平台。平台需要是可触摸的,所以我可以在游戏中旋转和移动它们,所以我把它变成了一个图像,而它原本只是一个精灵。 编辑: