NextJs给mdx文档图片添加缩放

July 28, 2024 (5mo ago)

使用 react-medium-image-zoom 插件和 Image 组件

安装 react-medium-image-zoom

sh
npm install react-medium-image-zoom

创建 ZoomableImage 组件

使用 nextjs 的 <Image> 组件不能全屏预览所以需要判断下,在放大的时候使用 img 标签显示原始尺寸,这种方法能充分利用 <Image> 的优化效果,并解决图片在放大时按原有尺寸显示的问题

ts
// components/ZoomableImage.tsx
'use client'

import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import Zoom from 'react-medium-image-zoom'
import 'react-medium-image-zoom/dist/styles.css'
import styles from './ZoomableImage.module.css'

const ZoomableImage = ({ src, alt, ...props }) => {
  const [originalDimensions, setOriginalDimensions] = useState({ width: 700, height: 475 })

  useEffect(() => {
    const img = new window.Image()
    img.src = src
    img.onload = () => {
      setOriginalDimensions({ width: img.width, height: img.height })
    }
  }, [src])

  return (
    <div className={styles.imageContainer}>
      <Zoom zoomImg={{ src, alt }}>
        <Image
          src={src}
          alt={alt}
          layout="responsive"
          width={originalDimensions.width}
          height={originalDimensions.height}
          className={styles.responsiveImage}
          {...props}
        />
      </Zoom>
    </div>
  )
}

export default ZoomableImage

创建 CSS 模块文件

创建一个 ZoomableImage.module.css 文件,定义图片容器的样式和响应式图片样式:

css
/* components/ZoomableImage.module.css */
.imageContainer {
  position: relative;
  width: 100%;
  max-width: 100%;
}

.responsiveImage {
  width: 100%;
  height: auto;
}

使用动态导入禁用 SSR

创建 MDXComponents.tsx 文件并使用 next/dynamic 动态导入 ZoomableImage 组件,并禁用 SSR

ts
// components/MDXComponents.tsx
import dynamic from 'next/dynamic'

const ZoomableImage = dynamic(() => import('./ZoomableImage'), { ssr: false })

const MDXComponents = {
  img: (props) => <ZoomableImage {...props} />
}

export default MDXComponents

MDX 文件中使用图片

在你的 MDX 文档中使用标准的 Markdown 语法来插入图片:

mdx
![Alt text](https://path/to/image.jpg)