簡體   English   中英

如何從數組中將背景圖像動態設置為卡片組件?

[英]How to dynamically set background image to card component from an array?

不確定如何描述這一點。 我有一張卡片網格,每張卡片都顯示不同的游戲,我想將每個背景圖像設置為游戲圖像。 這是我到目前為止的代碼:

const games = [
  {
    id: 1,
    background: '../images/game1.png',
    name: 'Game 1',
    description:
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vel sapien arcu. Donec sapien eros, efficitur blandit dui vitae, imperdiet consectetur nibh.',
  },
  {
    id: 2,
    background: '../images/game2.png',
    name: 'Game 2',
    description:
      'Nunc efficitur tincidunt malesuada. Pellentesque blandit sapien sed orci tristique molestie. Donec ut metus a sapien gravida convallis sed maximus neque. Aliquam consequat fringilla porta. Curabitur eget semper tortor.',
  },
];

export const GameCard = () => {
  const [isOpen, setIsOpen] = useState(null);

  return (
    <div id="card_wrapper">
      {games.map((game) => (
        <motion.div
          transition={{ layout: { duration: 1, type: 'spring' } }}
          layout
          onClick={() => setIsOpen(!isOpen)}
          key={game.id}
          class="card"
          style={{
            backgroundImage: `url(${game.background}) no-repeat`,
          }}
        >
          <motion.h2 layout="position"> {game.name} </motion.h2>
          {isOpen && (
            <motion.div
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              transition={{ duration: 1 }}
              class="expand"
            >
              <p> {game.description} </p>
            </motion.div>
          )}
        </motion.div>
      ))}
    </div>
  );
};

具體來說

        <motion.div
          transition={{ layout: { duration: 1, type: 'spring' } }}
          layout
          onClick={() => setIsOpen(!isOpen)}
          key={game.id}
          class="card"
          style={{
            backgroundImage: `url(${game.background}) no-repeat`,
          }}
        >

是我試圖將圖像作為背景傳遞但它不起作用的地方。

編輯顯示控制台:顯示正在通過但不渲染的圖像

實際上,您的 onClick 處理程序僅處理打開和關閉,您需要先在空數組上將背景 img 定義為 state,然后再在 jsx 上渲染,就像這樣

export const GameCard = () => {
const [isOpen, setIsOpen] = useState(null);
const [imgList, setImgList] = useState([]);
const imgRef = useRef()
const renderImgArr = (dataImg) => {
    setImgList([dataImg])
    /* ....define imgRef ...*/
}

return (
    <div id="card_wrapper">
      {games.map((game) => (
        <motion.div
          transition={{ layout: { duration: 1, type: 'spring' } }}
          layout
          // add renderImg and also possible to add setTimeOut on renderImgArr 
          onClick={() => setIsOpen(!isOpen) && renderImgArr}
          key={game.id}
          class="card"
          style={{
            backgroundImage: `url(${game.background}) no-repeat`,
          }}
        >
          <motion.h2 layout="position"> {game.name} </motion.h2>

         {/* render imgList with isOpen */}
          {isOpen && imgList && ( 
            <motion.div
              initial={{ opacity: 0 }}
             // define ref as a target reference 
              animate={imageRef.current.target, { opacity: 1 }}
              transition={{ duration: 1 }}
              class="expand"
            >
              <p> {game.description} </p>
            </motion.div>
          )}
        </motion.div>
      ))}
    </div>
  );
};

這並不完美,但你可以想象它是如何工作的,希望:)

Maycie,這是因為您直接在 DOM 上設置屬性。 當您渲染組件並在localhost上訪問它們時,您當前位於項目的根文件夾中。 所以你的代碼試圖做的實際上是 go 一個文件夾。 它行不通。 您有兩種選擇:

第一個選項

將圖像保存在項目內的公共文件夾中。 在與您的 src 文件夾相同的級別中,創建一個公用文件夾

在此處輸入圖像描述

並將您的背景保存在那里。 這是我的一個項目中的一個例子。 就我而言,我會在/assets/background/background.png上搜索背景圖像。

使用此選項(以我的文件夾結構為例),您的數組將如下所示,並且您不必更改組件中的代碼:

const games = [
  {
    id: 1,
    background: '/assets/background/game1.png',
    name: 'Game 1',
    description:
      'Lorem ipsum ...',
  }
];

第二個選項

在 CSS 上設置該屬性。 當您在樣式表中設置background-image: url(../images/game1.png)時,它將起作用,因為當您設置它時,組件還沒有被渲染。 因此,當它被渲染時,實際的 URL 將是由編譯器創建的,它能夠找到圖像。 為此,您必須為每個游戲創建一個 class 或類似的東西:

.game1{
    background-image: url('../images/game1.png'),
}

<motion.div
    transition={{ layout: { duration: 1, type: 'spring' } }}
    layout
    onClick={() => setIsOpen(!isOpen) && renderImgArr}
    key={game.id}
    class="card .game1"
>

最后的考慮:我會使用第一個選項。 它更簡潔,可以節省您編寫和應用大量自定義類的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM