iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0

Day05 是利用 CSS 的 flex 特性來完成伸縮畫廊,做出有互動效果的圖片展示面板

建立資料

  • 之後會用這些資料來展示圖片需要的資訊

const images = [
  {
    id: "325a8fddd0f7",
    imgUrl: "https://images.unsplash.com/photo-1443891238287-325a8fddd0f7",
    text: ["Hey", "Let's", "Dance"],
  },
  {
    id: "flashlight",
    imgUrl: "https://images.unsplash.com/24/flashlight.jpg",
    text: ["Give", "Take", "Receive"],
  },
  {
    id: "8fb5709d6d57",
    imgUrl: "https://images.unsplash.com/photo-1465188162913-8fb5709d6d57",
    text: ["Experience", "It", "Today"],
  },
  {
    id: "9032b6d10e3e",
    imgUrl: "https://images.unsplash.com/photo-1442522772768-9032b6d10e3e",
    text: ["Give", "All", "You can"],
  },
  {
    id: "2c087c332922",
    imgUrl: "https://images.unsplash.com/photo-1465156799763-2c087c332922",
    text: ["Life", "In", "Motion"],
  },
];

版面結構

  • openPanel 用來管理開關的面板

  • handlePanelClick 用來作開關

  • map 走訪陣列,並把需要的資訊傳進去

export default function FlexPanelGallery() {
  const [openPanel, setOpenPanel] = useState<string>("");

  const handlePanelClick = (id: string) => {
    setOpenPanel(openPanel === id ? "" : id);
  };

  return (
    <div className="min-h-screen overflow-hidden flex">
      {images.map((img) => (
        <Panel
          key={img.id}
          {...img}
          isOpen={openPanel === img.id}
          onClick={() => handlePanelClick(img.id)}
        />
      ))}
    </div>
  );
}

顯示面板

  • 這邊利用了 isOpen 來判斷是否開啟,假如開啟就讓版面伸展開來 flex-grow-[5]

  • 背景圖片使用 inline-style 來設定

  • 文字的初始位置設定在畫面以外的 -translate-y-[1000%],打開後才回到原來的位置,就能做出進場的動態效果惹

function Panel(props: PanelPropsType) {
  const { imgUrl, text, isOpen, onClick } = props;

  return (
    <div
      className={`ff-amatic bg-cover bg-center shadow-inner text-white text-center flex-1 flex flex-col justify-center items-center transition-all duration-700 ease-in-out ${
        isOpen ? "flex-grow-[5] text-4xl" : "text-2xl"
      }`}
      style={{ backgroundImage: `url(${imgUrl})` }}
      onClick={onClick}
    >
      <p
        className={`transform transition-transform duration-500 ${
          isOpen ? "translate-y-0" : "-translate-y-[1000%]"
        } uppercase text-shadow`}
      >
        {text[0]}
      </p>

      <p className="text-5xl my-4">{text[1]}</p>

      <p
        className={`transform transition-transform duration-500 ${
          isOpen ? "translate-y-0" : "translate-y-[1000%]"
        } uppercase text-shadow`}
      >
        {text[2]}
      </p>
    </div>
  );
}

DEMO

https://codesandbox.io/p/devbox/gjf37p

總結

  • CSS 的 translateY 可以用來改變位置

上一篇
[Day04]_Array-Cardio-Day1
下一篇
[Day06]_Type-Ahead
系列文
React30——用 React 探索 JavaScript30 的魅力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言