# img-previewer — 轻量 JavaScript 图片预览插件

> 零依赖的 JavaScript 图片预览 / 图片查看器 / lightbox 插件，仿 iOS 相册的丝滑缩放动画，gzip 后约 5 KB，可用于任何网站或框架（Vue、React、原生 HTML）。

[![GitHub license](https://img.shields.io/github/license/yue1123/img-previewer?style=flat-square)](https://github.com/yue1123/img-previewer/blob/main/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/yue1123/img-previewer?style=flat-square)](https://github.com/yue1123/img-previewer/stargazers)
<a href="https://www.npmjs.com/package/img-previewer">
<img src="https://img.shields.io/bundlephobia/minzip/img-previewer?color=%234ec820&style=flat-square" alt="img-previewer bundle size">
</a>
<a href="https://github.com/yue1123/img-previewer/releases">
<img src="https://img.shields.io/github/package-json/v/yue1123/img-previewer?color=f90&style=flat-square" alt="img-previewer version">
</a>

轻量且强大的 `javascript` 图片预览插件,丝滑的动画让你可以优雅的预览你的网站中的图片。开箱即用,你无需多余的配置(默认情况下)或改变页面 `html` 代码结构,即可在任何类型的网站中轻松启用该插件,升级你的用户体验

提供了这些功能:

1. 丝滑的可打断过渡动画
2. 鼠标滚轮缩放图片
3. 图标拖动图片
4. 上一张&下一张
5. 快捷键支持
6. 移动端手势(双指放大)支持
7. 多语言国际化支持
8. 图片加载监听

其他语言: [English](./README.md), [简体中文](./README.zh_cn.md).

**tips: 出于性能考虑,移动端没有做 swiper**

# 示例

[预览](https://yue1123.github.io/img-previewer/demo/)

# 如何使用

### NPM

```bash
npm i img-previewer
# 或者
yarn add img-previewer
```

### CDN

```html
<script src="https://cdn.jsdelivr.net/npm/img-previewer@2.1.6/dist/img-previewer.min.js"></script>
```

### 启用

```js
//js
import ImgPreviewer from 'img-previewer'
//css
import 'img-previewer/dist/index.css'

const imgPreviewer = new ImgPreviewer(css selector,{options...})
```

# 属性列表

|               | 类型   | 说明                                        | 默认值                                          |
| ------------- | ------ | ------------------------------------------- | ----------------------------------------------- |
| fillRatio     | number | 图片铺满预览区域的比例                      | 0.8(80%)                                        |
| dataUrlKey    | string | 图片地址取值的 key                          | src                                             |
| triggerEvent  | string | 触发事件                                    | click                                           |
| imageZoom     | object | 缩放图片的配置                              | {min: 1,max: 5,step: 0.1}                       |
| style         | object | 样式配置                                    | {modalOpacity: 0.6,headerOpacity: 0,zIndex: 99} |
| i18n          | object | tooltips 国际化配置                         | null                                            |
| bubblingLevel | number | 冒泡检测图片父元素是否被 css 样式隐藏的层级 | 0                                               |
| hideOriginal  | boolean | 预览时隐藏页面上原位的图片                | true                                            |
| toolbar       | boolean | 是否显示工具条,为 `false` 时只显示图片计数、关闭和上/下一张按钮 | true                                            |
| zoomable      | boolean | 是否允许放大缩小(按钮、滚轮、双指、快捷键) | true                                            |
| duration      | number | 打开和关闭动画的时长(毫秒),切换和缩放动画按比例跟随 | 400                                             |
| onBeforeShow  | function | 打开前调用,返回 `false` 取消打开          | -                                               |
| onShow        | function | 开始打开时调用                            | -                                               |
| onShown       | function | 打开动画结束后调用                        | -                                               |
| onChange      | function | 切换图片时调用                            | -                                               |
| onBeforeHide  | function | 关闭前调用,返回 `false` 取消关闭          | -                                               |
| onHide        | function | 开始关闭时调用(`onClose` 为别名)          | -                                               |
| onHidden      | function | 关闭动画结束后调用                        | -                                               |

> triggerEvent 的可选值有: click 和 dblclick

## 生命周期 hooks

调用顺序:`onBeforeShow` → `onShow` → `onShown` →(切换图片时 `onChange`)→ `onBeforeHide` → `onHide` → `onHidden`。

每个 hook 都会收到 `{ index, img }`,`img` 是页面上原来的图片元素;`onChange` 还会多一个 `prevIndex`。

```js
new ImgPreviewer('#app', {
	// 带 data-no-preview 的图片不预览
	onBeforeShow: ({ img }) => !img.hasAttribute('data-no-preview'),
	onChange: ({ index, prevIndex }) => console.log(prevIndex, '->', index),
	onHidden: ({ index }) => console.log('关闭时停在', index)
})
```

如果打开动画还没结束就关闭了,`onShown` 不会被调用。`destroy()` 不会触发任何 hook。
## bubblingLevel 说明

当你察觉到图片隐藏动画异常时,你应该尝试使用该属性。因为图片或图片父元素被某些 css 样式隐藏时,通过 js 的 api 是无法检测到的,所以需要自己根据实际情况,传入正确的向上查找层级来帮助插件完成正确的隐藏动画。如下所示,正确的 bubblingLevel 至少是 3

**为了性能考虑,不建议随意填写该属性值**

```html
<div style="opacity:0">
	<!-- 3 -->
	<div>
		<!-- 2 -->
		<img src="" alt="" />
		<!-- 1 -->
	</div>
</div>
```

**注意:**
目前检测元素或父元素被 css 样式隐藏只支持以下样式:

- opacity: 0;
- height: 0;
- width: 0;
- visibility: hidden;

## options.imageZoom

|      | 说明                   | 默认值   |
| ---- | ---------------------- | -------- |
| min  | 最小缩放比例           | 1(100%)  |
| max  | 最大缩放比例           | 5(500%)  |
| step | 滚轮每次滚动变化的比例 | 0.1      |

## options.style

|               | 说明               | 默认值 |
| ------------- | ------------------ | ------ |
| modalOpacity  | 预览区域蒙版透明度 | 0.6    |
| headerOpacity | 工具栏透明度       | 0      |
| zIndex        | 插件渲染的层级     | 99     |

## options.i18n

默认支持简体中文和英语,其他的需要自行配置
|              | 说明     |
| ------------ | -------- |
| RESET        | 重置     |
| ROTATE_LEFT  | 左旋转   |
| ROTATE_RIGHT | 右旋转   |
| CLOSE        | 关闭预览 |
| NEXT         | 下一张   |
| PREV         | 上一张   |
| ZOOM_IN      | 放大(可选,不传时使用内置文案) |
| ZOOM_OUT     | 缩小(可选,不传时使用内置文案) |

## 实例方法

|                    | Description          |
| ------------------ | -------------------- |
| update()           | 更新图片             |
| getTotalIndex()    | 获取最后一张图片的索引(张数 - 1) |
| show(index:number) | 显示                 |
| next()             | 下一张               |
| prev()             | 上一张               |
| hide()             | 关闭预览             |
| destroy()          | 销毁实例,移除事件监听和 DOM |

### 快捷键

| 按键 | 说明     |
| ---- | -------- |
| Esc  | 关闭预览 |
| <=   | 上一张   |
| =>   | 下一张   |
| + / - | 放大 / 缩小 |

# 更新图片

一些动态更新图片列表使用

```js
const imgPreviewer = new ImgPreviewer('body')
// 图片渲染到页面后调用
imgPreviewer.update()
```

# 幻灯片

```js
let timer = null
function play() {
	timer && clearInterval(timer)
	let index = 0
	a.show(index)
	timer = setInterval(() => {
		if (index < a.getTotalIndex()) {
			index++
		} else {
			index = 0
		}
		a.show(index)
	}, 2000)
}
play()
```
