npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-photo-view-vs2

v1.3.3

Published

An exquisite React photo preview component V2

Readme

react-photo-view-v2

一款超精致的 React 图片预览组件

在线文档 | 更新日志 |


✨ 特性

  • 🖼️ 完美的交互体验 - 支持触摸手势,拖动/平移/物理效果滑动,双指指定位置放大/缩小
  • 🎬 流畅的动画 - 全方面动画衔接,打开/关闭/回弹/触边,顺其自然的交互效果
  • 📱 响应式设计 - 图像自适应,自动计算合适的初始大小,完美适配各种屏幕
  • 🎮 键盘导航 - 支持方向键切换、ESC 关闭,完美适配桌面端
  • 🎨 高度可定制 - 支持自定义 <video /><iframe /> 或任意 HTML 元素的预览
  • 🔧 强大的 API - 支持命令式控制、受控模式、自定义缩放范围等高级功能
  • 🌐 SSR 支持 - 支持服务端渲染
  • 📦 体积小巧 - 仅 7KB Gzipped,基于 TypeScript 开发
  • 💡 简单易用 - API 设计简洁,5 分钟快速上手

📦 安装

使用 npm

npm install react-photo-view

使用 yarn

yarn add react-photo-view

使用 pnpm

pnpm add react-photo-view

🚀 快速开始

1. 基本用法

最简单的使用方式,只需要 3 步:

import { PhotoProvider, PhotoView } from 'react-photo-view';
import 'react-photo-view/dist/react-photo-view.css';

function App() {
  return (
    <PhotoProvider>
      <PhotoView src="/path/to/image.jpg">
        <img src="/path/to/thumbnail.jpg" alt="" />
      </PhotoView>
    </PhotoProvider>
  );
}

说明:

  • PhotoProvider - 图片预览容器,包裹需要预览的图片
  • PhotoView - 单个图片预览组件,点击其子元素会触发预览
  • 必须引入 CSS 文件才能正常显示

2. 多图预览

展示多张图片,自动支持左右切换:

function Gallery() {
  const images = [
    '/image1.jpg',
    '/image2.jpg',
    '/image3.jpg',
  ];

  return (
    <PhotoProvider>
      <div className="gallery">
        {images.map((item, index) => (
          <PhotoView key={index} src={item}>
            <img src={item} alt="" />
          </PhotoView>
        ))}
      </div>
    </PhotoProvider>
  );
}

3. 自定义缩放范围

控制图片的最小和最大缩放倍数:

function CustomScale() {
  return (
    <PhotoProvider 
      minScale={0.5}  // 最小可缩小到 0.5 倍
      maxScale={10}   // 最大可放大到 10 倍
    >
      <PhotoView src="/image.jpg">
        <img src="/thumbnail.jpg" alt="" />
      </PhotoView>
    </PhotoProvider>
  );
}

使用场景:

  • 设置 minScale < 1 可以让图片缩小到比屏幕适应尺寸更小
  • 增大 maxScale 可以查看更多细节

4. 命令式控制

使用 Ref API 主动打开或关闭预览:

import { useRef } from 'react';
import { PhotoProvider, PhotoView, PhotoProviderRef } from 'react-photo-view';

function ControlledGallery() {
  const photoRef = useRef<PhotoProviderRef>(null);

  return (
    <>
      <button onClick={() => photoRef.current?.show(0)}>
        打开第一张图片
      </button>
      <button onClick={() => photoRef.current?.close()}>
        关闭预览
      </button>

      <PhotoProvider ref={photoRef}>
        <PhotoView src="/image1.jpg">
          <img src="/image1.jpg" alt="" />
        </PhotoView>
        <PhotoView src="/image2.jpg">
          <img src="/image2.jpg" alt="" />
        </PhotoView>
      </PhotoProvider>
    </>
  );
}

5. 受控模式

完全控制预览的显示状态:

import { useState } from 'react';

function ControlledMode() {
  const [visible, setVisible] = useState(false);
  const [index, setIndex] = useState(0);

  return (
    <>
      <button onClick={() => { setIndex(0); setVisible(true); }}>
        查看图片
      </button>

      <PhotoProvider
        visible={visible}
        onVisibleChange={setVisible}
        onIndexChange={setIndex}
      >
        <PhotoView src="/image.jpg">
          <img src="/thumbnail.jpg" alt="" />
        </PhotoView>
      </PhotoProvider>
    </>
  );
}

📖 常用配置

PhotoProvider 属性

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | minScale | 最小缩放倍数 | number | 1 | | maxScale | 最大缩放倍数 | number | 6 | | loop | 是否循环预览 | boolean \| number | 3 | | maskClosable | 点击背景是否关闭 | boolean | true | | photoClosable | 点击图片是否关闭 | boolean | false | | pullClosable | 下拉是否关闭 | boolean | true | | bannerVisible | 是否显示导航栏 | boolean | true | | visible | 受控模式:是否显示 | boolean | - | | onVisibleChange | 显示状态改变回调 | (visible: boolean, index: number) => void | - | | onIndexChange | 索引改变回调 | (index: number) => void | - |

PhotoProviderRef 方法

通过 ref 可以调用以下方法:

interface PhotoProviderRef {
  show: (index?: number) => void;  // 显示指定索引的图片
  close: () => void;                // 关闭预览
}

PhotoView 属性

| 属性 | 说明 | 类型 | 默认值 | |------|------|------|--------| | src | 图片地址 | string | - | | overlay | 自定义覆盖层内容 | ReactNode | - | | width | 自定义宽度 | number | - | | height | 自定义高度 | number | - |


💡 使用技巧

1. 不同的缩略图和预览图

<PhotoView src="/high-quality.jpg">
  <img src="/thumbnail.jpg" alt="" />
</PhotoView>

2. 自定义触发方式

<PhotoView src="/image.jpg" triggers={['onClick', 'onDoubleClick']}>
  <img src="/image.jpg" alt="" />
</PhotoView>

3. 预览视频

<PhotoView
  width={800}
  height={600}
  render={() => (
    <video src="/video.mp4" controls />
  )}
>
  <img src="/video-poster.jpg" alt="" />
</PhotoView>

4. 添加图片描述

<PhotoView
  src="/image.jpg"
  overlay={
    <div style={{ padding: 20, color: 'white' }}>
      这是图片的描述信息
    </div>
  }
>
  <img src="/thumbnail.jpg" alt="" />
</PhotoView>

5. 禁用某些交互

<PhotoProvider
  maskClosable={false}    // 禁用点击背景关闭
  pullClosable={false}    // 禁用下拉关闭
  photoClosable={true}    // 启用点击图片关闭
>
  {/* ... */}
</PhotoProvider>

🎯 使用场景

电商网站

function ProductGallery({ product }) {
  return (
    <PhotoProvider>
      <div className="product-images">
        {product.images.map((img, index) => (
          <PhotoView key={index} src={img.original}>
            <img src={img.thumbnail} alt={product.name} />
          </PhotoView>
        ))}
      </div>
    </PhotoProvider>
  );
}

社交媒体

function PostImages({ images }) {
  return (
    <PhotoProvider bannerVisible={true} loop={true}>
      <div className="post-images">
        {images.map((img, index) => (
          <PhotoView key={index} src={img}>
            <img src={img} alt="" style={{ width: 200, height: 200, objectFit: 'cover' }} />
          </PhotoView>
        ))}
      </div>
    </PhotoProvider>
  );
}

相册应用

function Album({ photos }) {
  const photoRef = useRef<PhotoProviderRef>(null);

  return (
    <div>
      <button onClick={() => photoRef.current?.show(0)}>
        幻灯片播放
      </button>

      <PhotoProvider 
        ref={photoRef}
        loop={true}
        minScale={0.3}
        maxScale={8}
      >
        <div className="grid">
          {photos.map((photo, index) => (
            <PhotoView key={index} src={photo.url}>
              <img src={photo.thumbnail} alt={photo.title} />
            </PhotoView>
          ))}
        </div>
      </PhotoProvider>
    </div>
  );
}

🔧 高级用法

自定义工具栏

<PhotoProvider
  toolbarRender={({ onScale, scale, rotate, onRotate }) => (
    <div className="custom-toolbar">
      <button onClick={() => onScale(scale + 1)}>放大</button>
      <button onClick={() => onScale(scale - 1)}>缩小</button>
      <button onClick={() => onRotate(rotate + 90)}>旋转</button>
    </div>
  )}
>
  {/* ... */}
</PhotoProvider>

自定义加载效果

<PhotoProvider
  loadingElement={<div className="custom-loading">加载中...</div>}
>
  {/* ... */}
</PhotoProvider>

处理加载失败

<PhotoProvider
  brokenElement={
    <div className="custom-broken">
      图片加载失败
    </div>
  }
>
  {/* ... */}
</PhotoProvider>

⚙️ TypeScript 支持

完整的 TypeScript 类型定义:

import type { 
  PhotoProviderRef,
  PhotoProviderProps,
  PhotoProviderBase,
  DataType,
  OverlayRenderProps 
} from 'react-photo-view';

// 使用 ref
const photoRef = useRef<PhotoProviderRef>(null);

// 自定义渲染函数
const overlayRender = (props: OverlayRenderProps) => {
  return <div>{/* 自定义内容 */}</div>;
};

❓ 常见问题

1. 图片不显示?

确保已经引入了 CSS 文件:

import 'react-photo-view/dist/react-photo-view.css';

2. 如何在预览中使用高清图?

使用不同的 src 即可:

<PhotoView src="/high-quality.jpg">
  <img src="/thumbnail.jpg" alt="" />
</PhotoView>

3. 如何禁用某些图片的预览?

不使用 PhotoView 包裹即可:

<PhotoProvider>
  <PhotoView src="/image1.jpg">
    <img src="/image1.jpg" alt="" />
  </PhotoView>
  
  {/* 这张图片不会被预览 */}
  <img src="/image2.jpg" alt="" />
</PhotoProvider>

4. 如何在 Next.js 中使用?

// app/page.tsx 或 pages/index.tsx
'use client'; // 如果使用 App Router

import { PhotoProvider, PhotoView } from 'react-photo-view';
import 'react-photo-view/dist/react-photo-view.css';

export default function Page() {
  return (
    <PhotoProvider>
      {/* ... */}
    </PhotoProvider>
  );
}

5. 缩放太慢或太快?

可以自定义动画速度:

<PhotoProvider speed={(type) => (type === 1 ? 300 : 200)}>
  {/* ... */}
</PhotoProvider>

🌐 浏览器兼容性

  • Chrome (最新版)
  • Firefox (最新版)
  • Safari (最新版)
  • Edge (最新版)
  • 移动端浏览器

📚 更多资源


🤝 贡献

欢迎提交 Issue 和 Pull Request!