@gem-mine/rmc-gallery

移动端图片查看器组件

Usage no npm install needed!

<script type="module">
  import gemMineRmcGallery from 'https://cdn.skypack.dev/@gem-mine/rmc-gallery';
</script>

README

react图片查看器组件


图片查看器

何时使用

  • 查看图片的时候

安装

npm install @gem-mine/rmc-gallery --save

运行

# 默认开启服务器,地址为 :http://localhost:8000/

# 能在ie9+下浏览本站,修改代码后自动重新构建,且能在ie10+运行热更新,页面会自动刷新
npm run start

# 构建生产环境静态文件,用于发布文档
npm run site

代码演示

在线示例:https://gem-mine.github.io/gem-mine/rmc-gallery/site/

基本

基本用法。

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const imageOriginal = [
      {
        original: 'http://这是个无效的图片路径',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg',
        description: <div style={{overflowY: 'scroll', maxHeight: '100px'}}>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/></div>
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]
const images = [...imageOriginal, ...imageOriginal, ...imageOriginal, ...imageOriginal]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          showToolbar
          maxZoomSize={2.5}
          minZoomSize={0.3}
          zoomStep={0.4}
          images={images}
          spinClass={<div className={`demo-custom-spin`}>loading...</div>}
          onClose={this.closeGallery} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>查看图片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);
.fish-gallery-image img {
  max-width: none;
}
.demo-custom-spin {
  font-size: 20px;
  color: #fff;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

事件回调

事件发生时触发回调

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const imageOriginal = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg',
        description: '图片描述的文字描述'
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]
const images = [...imageOriginal, ...imageOriginal, ...imageOriginal, ...imageOriginal]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  hanldeMovePrev = (currentIndex) => {
    console.log(`onMovePrev 图片索引:${currentIndex}`)
  }
  hanldeMoveNext = (currentIndex) => {
    console.log(`onMoveNext 图片索引:${currentIndex}`)
  }
  handleThumbnailClick = (index) => {
    console.log(`onMoveNext 图片索引:${index}`)
  }
  handleImageLoad = () => {
    console.log('图片加载成功')
  }
  handleImageLoadError = () => {
    console.log('图片加载失败')
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          onClose={this.closeGallery}
          onMovePrev={this.hanldeMovePrev}
          onMoveNext={this.hanldeMoveNext}
          onThumbnailClick={this.handleThumbnailClick}
          onImageLoad={this.handleImageLoad}
          onImageLoadError={this.handleImageLoadError} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>查看图片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

自动播放

自动播放图片数组中的图片

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const images = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          infinite={true}
          autoPlay={true}
          showThumbnail={false}
          keymap={false}
          playSpeed={4000}
          onClose={this.closeGallery} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>显示照片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

配置工具栏

自定义工具栏

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const images = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  handleCustomToolbarItemClick = (obj) => {
    alert(`当前是第${obj.currentIndex + 1}张图片`)
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          showToolbar
          rotateLeftIcon={<span>左转</span>}
          toolbarConfig={{
            rotateLeft: true,
            rotateRight: true,
            autoPlay: true
          }}
          customToolbarItem={(obj) => {
            return <span onClick={this.handleCustomToolbarItemClick.bind(this, obj)} className='fish-gallery-toolbar-item'  type="question-circle-o">点击显示当前是第几张</span>
          }}
          onClose={this.closeGallery} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>显示照片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

设置起始图片

设置从起始图片开始显示。

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const images = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]

class App extends React.Component {
  state = {
    isGallery: false,
    startIndex: 0
  }
  openGallery = (index) => {
    this.setState({
      isGallery: true,
      startIndex: index
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          infinite={false}
          startIndex={this.state.startIndex}
          onClose={this.closeGallery} />
      )
    }

    const clickImages = images.map((item, index) => {
      return <img key={index} src={item.thumbnail} className="start-index-thumbnail-item" onClick={() => {this.openGallery(index)}} />
    })

    return (
      <div>
       {gallery}
       {clickImages}
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);
.start-index-thumbnail-item {
  height: 50px;
  width: 100px;
  padding: 0 10px;
}

只有图片一张的时候

图片只有一张的时候,不显示左右箭头和图片下标,自动播放以及缩略图。

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const images = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      }
    ]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          onClose={this.closeGallery} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>显示照片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

自定义图标

自定义图标。

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const imageOriginal = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg',
        description: (<div style={{overflowY: 'scroll', maxHeight: '100px'}}>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/>图片描述<br/></div>)
      }
    ]
const images = [...imageOriginal, ...imageOriginal, ...imageOriginal, ...imageOriginal]

class App extends React.Component {
  state = {
    isGallery: false,
  }
  openGallery = () => {
    this.setState({
      isGallery: true
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <Gallery
          images={images}
          closeIcon={'关闭'}
          prevIcon={<span className={'demo-goto-page'}>上一页</span>}
          nextIcon={<span className={'demo-goto-page'}>下一页</span>}
          zoomInIcon={<span style={{color: "#fff"}}>放大 </span>}
          zoomOutIcon={<span style={{color: "#fff"}}>缩小 </span>}
          rotateRightIcon={<span style={{color: "#fff"}}>右转 </span>}
          rotateLeftIcon={<span style={{color: "#fff"}}>左转 </span>}
          playIcon={<span style={{color: "#fff"}}>播放 </span>}
          pauseIcon={<span style={{color: "#fff"}}>暂停 </span>}
          onClose={this.closeGallery} />
      )
    }
    return (
      <div>
       {gallery}
       <button onClick={this.openGallery}>查看图片</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);
.demo-goto-page {
  font-size: 15px;
}

在文档中显示

在文档中显示。移动端不支持

import "@gem-mine/rmc-gallery/lib/style/";
import Gallery from '@gem-mine/rmc-gallery'

const imageOriginal = [
      {
        original: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5.jpg',
        thumbnail: '//img.zmei.me/gm/a801236bjw1ez812gy3g8j20rs0rs0z5-thumb.jpg',
        description: <div>图片描述</div>
      },
      {
        original: '//img.zmei.me/gm/26828021367384226.jpg',
        thumbnail: '//img.zmei.me/gm/26828021367384226-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/priview.jpg',
        thumbnail: '//img.zmei.me/gm/priview-thumb.jpg'
      },
      {
        original: '//img.zmei.me/gm/lazyimg1.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg1-thumb.jpg',
      },
      {
        original: '//img.zmei.me/gm/lazyimg2.jpg',
        thumbnail: '//img.zmei.me/gm/lazyimg2-thumb.jpg'
      }
    ]
const images = [...imageOriginal, ...imageOriginal, ...imageOriginal, ...imageOriginal]
class App extends React.Component {
  state = {
    isGallery: true,
  }
  openGallery = (index) => {
    this.setState({
      isGallery: true,
    })
  }
  closeGallery = () => {
    this.setState({
      isGallery: false
    })
  }
  render() {
    let gallery = null
    if (this.state.isGallery) {
      gallery = (
        <div style={{height: '400px'}}>
          <Gallery
            images={images}
            infinite={false}
            maxZoomSize={2}
            minZoomSize={0.2}
            zoomStep={0.01}
            displayMode={'inline'}
            onClose={this.closeGallery} />
        </div>
      )
    }

    return (
      <div>
        {gallery}
        {this.state.isGallery ? null : <button onClick={this.openGallery}>查看图片</button>}
      </div>
    );
  }
}

ReactDOM.render(<App />, mountNode);

API

参数 说明 类型 默认值
displayMode 显示模式, 有全屏遮罩模式和插入文档流模式(移动端不支持) Enum{ 'inline', 'modal' } modal
images 数组对象,存放图片信息 Gallery.images[]
showToolbar 是否显示工具条 boolean true
showThumbnail 是否显示缩略图(移动端不显示) boolean true
keymap 是否开启默认键盘事件(esc关闭,左右选图片) boolean true
startIndex 初始进入显示第几张图 number 0
toolbarConfig 配置工具栏 object toolbarConfig: { autoPlay: true, rotateLeft: true, rotateRight: true, zoomIn: true, zoomOut: true }
playSpeed 自动播放速度(单位毫秒) number 2000
infinite 是否无限循环 boolean false
spinClass 传入spin组件,替代自带的spin图 react.element
customToolbarItem(images: object[], src: string, currentIndex: number) 自定义toolbar;参数images是传入的图片数组,参数src是当前图片的原图地址,currentIndex是当前图片的索引 function () => {}
onClose 关闭回调 function
onMovePrev(currentIndex: Number) 点击上一页回调,参数为当前图片索引 function
onMoveNext(currentIndex: Number) 点击下一页回调,参数为当前图片索引 function
onThumbnailClick(index: Number) 点击缩略图回调,参数为缩略图表示的图片索引 function
onImageLoad 图片加载完成回调 function
onImageLoadError 图片加载失败回调 function
closeIcon 自定义关闭图标 ReactNode
thumbnailIcon 自定义开关缩略图图标 ReactNode
prevIcon 自定义上一页图标 ReactNode
nextIcon 自定义下一页图标 ReactNode
maxZoomSize 最大可缩放比例 number 3
minZoomSize 最小可缩放比例 number 0.2
mouseWheelZoom 开启鼠标滚轮放大缩小 boolean true
mouseZoomDirection 自定义鼠标滚轮控制缩放的方向,参数为滚轮事件对象。返回true图片缩小,返回false图片放大,默认win下滚轮向上放大,向下缩小;mac下相反 (e) => boolean isMac ? e.deltaY < 0 : e.deltaY > 0
zoomInIcon 自定义放大图标 ReactNode
zoomOutIcon 自定义缩小图标 ReactNode
rotateRightIcon 自定义右转图标 ReactNode
rotateLeftIcon 自定义左转图标 ReactNode
playIcon 自定义播放图标 ReactNode
pauseIcon 自定义暂停图标 ReactNode

images

配置每张图片信息,配置项如下

参数 说明 类型 默认值
original 图片的原图地址 string
thumbnail 图片的缩略图地址,若未配置,则使用原图 string
description 图片的描述 react.element | string

移动端

移动端与PC端有几点不同

  1. 顶部工具栏默认关闭
  2. 左右看图箭头取消,但可以通过手势左右滑动进行图片前后张切换
  3. 无底部缩略图