【NextJS】Zoom in on an image during hover

1. 概要

前回は画像を切り取りし、保存する内容についてでした。今回はマウスを当てると画像が拡大される内容になります。

対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。

2. nodeのインストール

こちらを参考

3. プロジェクトを作成

3-1-1. こちらを参考

4. 必要なライブラリをインストール

4-1-1. こちらを参考

npm install --save react-cropper

5. ソースコード

※前回より差分のみを記載

5-1-1. src/app/components/component13/image-zoom.tsx

import { Box, Paper } from "@mui/material";
import Image from "next/image";
import { useState } from "react";

type Props = {
  imgSrc: string;
  imgWidth: number;
  imgHeight: number;
  imgScale: number;
};

const ImageZoom = (props: Props) => {
  const [isHovered, setIsHovered] = useState<boolean>(false);
  const imgScaledWidth: number = props.imgWidth * props.imgScale;
  const imgScaledHeight: number = props.imgHeight * props.imgScale;

  return (
    <Box
      sx={{
        position: "relative",
        width: props.imgWidth,
        height: props.imgHeight,
      }}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      <Image
        src={props.imgSrc}
        alt="Zoomable"
        fill
        style={{ objectFit: "cover", borderRadius: 8 }}
      />
      {isHovered && (
        <Paper
          elevation={6}
          sx={{
            position: "absolute",
            top: 0,
            left: 0,
            width: imgScaledWidth,
            height: imgScaledHeight,
            borderRadius: 2,
            zIndex: 10,
            overflow: "hidden",
          }}
        >
          <Image
            src={props.imgSrc}
            alt="Zoom Popup"
            fill
            style={{ objectFit: "cover", borderRadius: 8 }}
          />
        </Paper>
      )}
    </Box>
  );
};

export default ImageZoom;

5-1-2. src/app/components/component13/client-page.tsx

"use client";

import ImageZoom from "./image-zoom";

const ClientPage = () => {
  const imgSrc: string = "/panko-lineup.png";
  const imgWidth: number = 150;
  const imgHeight: number = 150;
  const imgScale: number = 2;
  return (
    <ImageZoom
      imgSrc={imgSrc}
      imgWidth={imgWidth}
      imgHeight={imgHeight}
      imgScale={imgScale}
    />
  );
};

export default ClientPage;

5-1-3. src/app/components/component13/page.module.scss

.component {
  & ul {
    margin-left: 20px;
    & li {
      list-style: disc;
    }
  }
}

5-1-4. src/app/components/component13/page.tsx

import Divider from "@mui/material/Divider";
import GoBack from "@/lib/components/go-back";
import scss from "./page.module.scss";
import ClientPage from "./client-page";

const Component13 = () => {
  return (
    <div className={scss.component}>
      <GoBack />
      <br />
      <br />
      <ul>
        <li>Image Zoom</li>
        <ul>
          <li>Hover : Mouse over</li>
        </ul>
      </ul>
      <Divider sx={{ marginTop: 2, marginBottom: 2 }} />
      <div>
        <ClientPage />
      </div>
    </div>
  );
};

export default Component13;

5-1-5. src/app/components/page.module.scss

.components {
  color: blue;
  & ul {
    margin-left: 20px;
    & li {
      list-style: disc;
    }
  }
}

5-1-6. src/app/components/page.tsx

"use client";

import React from "react";
import { Link } from "@mui/material";

import scss from "./page.module.scss";

const Components = () => {
  return (
    <div className={scss.components}>
      <ul>
        <li>
          <Link href="/components/component01" underline="hover">
            Component01
          </Link>
        </li>
        <li>
          <Link href="/components/component02" underline="hover">
            Component02
          </Link>
        </li>
        <li>
          <Link href="/components/component03" underline="hover">
            Component03
          </Link>
        </li>
        <li>
          <Link href="/components/component04" underline="hover">
            Component04
          </Link>
        </li>
        <li>
          <Link href="/components/component05" underline="hover">
            Component05
          </Link>
        </li>
        <li>
          <Link href="/components/component06" underline="hover">
            Component06
          </Link>
        </li>
        <li>
          <Link href="/components/component07" underline="hover">
            Component07
          </Link>
        </li>
        <li>
          <Link href="/components/component08" underline="hover">
            Component08
          </Link>
        </li>
        <li>
          <Link href="/components/component09" underline="hover">
            Component09
          </Link>
        </li>
        <li>
          <Link href="/components/component10" underline="hover">
            Component10
          </Link>
        </li>
        <li>
          <Link href="/components/component11" underline="hover">
            Component11
          </Link>
        </li>
        <li>
          <Link href="/components/component12" underline="hover">
            Component12
          </Link>
        </li>
        <li>
          <Link href="/components/component13" underline="hover">
            Component13
          </Link>
        </li>
      </ul>
    </div>
  );
};

export default Components;

6. サーバーを起動

npm run dev

7. ブラウザで確認

  • http://localhost:3000

7-1-1. 原本

7-2-1. 拡大

8. ディレクトリの構造

省略

9. 備考

今回はマウスを当てると画像が拡大される内容についてでした。

10. 参考

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

  1. 【NextJS】Dynamic Routes

  2. 【NextJS】Streaming with Suspense

  3. 【NextJS】TextField

  4. 【NextJS】FullCalendar

  5. 【NextJS】AWS SAMを使いCLIでデプロイしたLambda関…

  6. 【NextJS】Server Actions with MySQL

最近の記事

制作実績一覧

  1. Checkeys