Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageViewer preview component supports self-defined preview content #6825

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/components/image-viewer/demos/demo1.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@

.footerButton {
font-size: var(--adm-font-size-4);
color: #ffffff;
color: #fff;
line-height: 1;
padding: 10px 16px;
background-color: rgba(153, 153, 153, 0.4);
border-radius: 100px;
display: inline-block;
cursor: pointer;
}
.image-render {
width: 100%;
height: 100%;
display: flex;
align-items: center;
}
.custom-render {
color: #1677ff;
background: #fff;
width: 200px;
height: 100px;
border-radius: 2px;
padding: 8px;
}
73 changes: 70 additions & 3 deletions src/components/image-viewer/demos/demo1.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState } from 'react'
import { ImageViewer, Button } from 'antd-mobile'
import { Button, ImageViewer } from 'antd-mobile'
import { DemoBlock } from 'demos'
import { demoImage, demoImages } from './images'
import React, { useState } from 'react'
import styles from './demo1.less'
import { demoImage, demoImages } from './images'

// 单张图片预览
const Single = () => {
Expand Down Expand Up @@ -95,6 +95,66 @@ const ViewWithFooter = () => {
)
}

const ViewImageRender = () => {
const [visible, setVisible] = useState(false)

return (
<>
<Button
onClick={() => {
setVisible(true)
}}
>
显示内容
</Button>
<ImageViewer
visible={visible}
onClose={() => {
setVisible(false)
}}
imageRender={() => (
<div className={styles['image-render']}>
<video
muted
width='100%'
controls
src='https://mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*uYT7SZwhJnUAAAAAAAAAAAAADgCCAQ'
/>
</div>
)}
/>
</>
)
}

// 多张图片预览
const MultiViewImageRender = () => {
const [visible, setVisible] = useState(false)
return (
<>
<Button
onClick={() => {
setVisible(true)
}}
>
显示图片
</Button>
<ImageViewer.Multi
images={demoImages}
visible={visible}
imageRender={(image?: string, index?: number) => {
if (index === 1)
return <div className={styles['custom-render']}>自定义渲染内容</div>
}}
defaultIndex={1}
onClose={() => {
setVisible(false)
}}
/>
</>
)
}

export default () => {
return (
<>
Expand Down Expand Up @@ -134,6 +194,13 @@ export default () => {
<DemoBlock title='自定义底部额外内容'>
<ViewWithFooter />
</DemoBlock>

<DemoBlock title='自定义预览内容单张'>
<ViewImageRender />
</DemoBlock>
<DemoBlock title='自定义预览内容多张'>
<MultiViewImageRender />
</DemoBlock>
</>
)
}
16 changes: 10 additions & 6 deletions src/components/image-viewer/image-viewer.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import classNames from 'classnames'
import type { FC, ReactNode } from 'react'
import React, {
forwardRef,
useCallback,
useImperativeHandle,
useRef,
useState,
useCallback,
} from 'react'
import type { FC, ReactNode } from 'react'
import { mergeProps } from '../../utils/with-default-props'
import {
GetContainer,
renderToContainer,
} from '../../utils/render-to-container'
import { mergeProps } from '../../utils/with-default-props'
import Mask from '../mask'
import SafeArea from '../safe-area'
import { Slide } from './slide'
import { Slides, SlidesRef } from './slides'
import classNames from 'classnames'

const classPrefix = `adm-image-viewer`

Expand All @@ -27,6 +27,7 @@ export type ImageViewerProps = {
onClose?: () => void
afterClose?: () => void
renderFooter?: (image: string) => ReactNode
imageRender?: () => ReactNode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

接受一下当前 image 的 url ,否则不知道是哪一个~

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

接受一下当前 image 的 url ,否则不知道是哪一个~

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个定义看起来还是没有变哈?

classNames?: {
mask?: string
body?: string
Expand Down Expand Up @@ -57,11 +58,12 @@ export const ImageViewer: FC<ImageViewerProps> = p => {
props?.classNames?.body
)}
>
{props.image && (
{(props.image || typeof props.imageRender === 'function') && (
<Slide
image={props.image}
onTap={props.onClose}
maxZoom={props.maxZoom}
imageRender={props.imageRender}
/>
)}
</div>
Expand All @@ -80,12 +82,13 @@ export type MultiImageViewerRef = SlidesRef

export type MultiImageViewerProps = Omit<
ImageViewerProps,
'image' | 'renderFooter'
'image' | 'renderFooter' | 'imageRender'
> & {
images?: string[]
defaultIndex?: number
onIndexChange?: (index: number) => void
renderFooter?: (image: string, index: number) => ReactNode
imageRender?: (image: string, index: number) => ReactNode
}

const multiDefaultProps = {
Expand Down Expand Up @@ -140,6 +143,7 @@ export const MultiImageViewer = forwardRef<
images={props.images}
onTap={props.onClose}
maxZoom={props.maxZoom}
imageRender={props.imageRender}
/>
)}
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/components/image-viewer/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ You need to click on the picture to view the details and use it with the thumbna
| maxZoom | The maximum zoom ratio | `number \| 'auto'` | `3` |
| onClose | Triggered when it is closed | `() => void` | - |
| renderFooter | Render extra content on footer | `(image: string) => ReactNode` | - |
| imageRender | Custom rendering content | `() => ReactNode` | - |
| visible | Whether to show or hide | `boolean` | `false` |

## ImageViewer.Multi
Expand All @@ -34,6 +35,7 @@ On the basis of `ImageViewer`, the following props have been added:
| images | Url list of image resources | `string[]` | - |
| onIndexChange | Triggered when the picture is switched | `(index: number) => void` | - |
| renderFooter | Render extra content on footer | `(image: string, index: number) => ReactNode` | - |
| imageRender | Custom rendering content | `(image: string, index: number) => ReactNode` | - |

At the same time, the `image` prop is removed.

Expand Down
2 changes: 2 additions & 0 deletions src/components/image-viewer/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| maxZoom | 最大缩放比例 | `number \| 'auto'` | `3` |
| onClose | 关闭时触发 | `() => void` | - |
| renderFooter | 渲染底部额外内容 | `(image: string) => ReactNode` | - |
| imageRender | 自定义渲染内容 | `() => ReactNode` | - |
| visible | 是否显示 | `boolean` | `false` |

## ImageViewer.Multi
Expand All @@ -32,6 +33,7 @@
| images | 图片资源的 url 列表 | `string[]` | - |
| onIndexChange | 切换图片时触发 | `(index: number) => void` | - |
| renderFooter | 渲染底部额外内容 | `(image: string, index: number) => ReactNode` | - |
| imageRender | 自定义渲染内容 | `(image: string, index: number) => ReactNode` | - |

其他属性同 `ImageViewer`,但是去掉了 `image` 属性。

Expand Down
35 changes: 22 additions & 13 deletions src/components/image-viewer/slide.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import React, { useRef } from 'react'
import type { FC, MutableRefObject } from 'react'
import { useSpring, animated } from '@react-spring/web'
import { animated, useSpring } from '@react-spring/web'
import { useSize } from 'ahooks'
import { rubberbandIfOutOfBounds } from '../../utils/rubberband'
import { useDragAndPinch } from '../../utils/use-drag-and-pinch'
import type { FC, MutableRefObject, ReactNode } from 'react'
import React, { useRef } from 'react'
import { bound } from '../../utils/bound'
import type { Matrix } from '../../utils/matrix'
import * as mat from '../../utils/matrix'
import { rubberbandIfOutOfBounds } from '../../utils/rubberband'
import { useDragAndPinch } from '../../utils/use-drag-and-pinch'

const classPrefix = `adm-image-viewer`

type Props = {
image: string
image?: string
maxZoom: number | 'auto'
onTap?: () => void
onZoomChange?: (zoom: number) => void
dragLockRef?: MutableRefObject<boolean>
imageRender?: (image?: string, index?: number) => ReactNode
index?: number
}

export const Slide: FC<Props> = props => {
const { dragLockRef, maxZoom } = props
const { dragLockRef, maxZoom, imageRender, index } = props
const initialMartix = useRef<boolean[]>([])
const controlRef = useRef<HTMLDivElement>(null)
const imgRef = useRef<HTMLImageElement>(null)
Expand Down Expand Up @@ -295,6 +297,9 @@ export const Slide: FC<Props> = props => {
}
)

const customRendering =
typeof imageRender === 'function' && imageRender?.(props.image, index)

return (
<div className={`${classPrefix}-slide`}>
<div className={`${classPrefix}-control`} ref={controlRef}>
Expand All @@ -304,12 +309,16 @@ export const Slide: FC<Props> = props => {
matrix,
}}
>
<img
ref={imgRef}
src={props.image}
draggable={false}
alt={props.image}
/>
{customRendering ? (
customRendering
) : (
<img
ref={imgRef}
src={props.image}
draggable={false}
alt={props.image}
/>
)}
</animated.div>
</div>
</div>
Expand Down
16 changes: 12 additions & 4 deletions src/components/image-viewer/slides.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React, { forwardRef, useImperativeHandle, useRef } from 'react'
import { animated, useSpring } from '@react-spring/web'
import { useDrag } from '@use-gesture/react'
import { useSpring, animated } from '@react-spring/web'
import { Slide } from './slide'
import { convertPx } from '../../utils/convert-px'
import React, {
ReactNode,
forwardRef,
useImperativeHandle,
useRef,
} from 'react'
import { bound } from '../../utils/bound'
import { convertPx } from '../../utils/convert-px'
import { Slide } from './slide'

const classPrefix = `adm-image-viewer`

Expand All @@ -13,6 +18,7 @@ export type SlidesType = {
maxZoom: number
defaultIndex: number
onIndexChange?: (index: number) => void
imageRender?: (image: string, index: number) => ReactNode
}
export type SlidesRef = {
swipeTo: (index: number, immediate?: boolean) => void
Expand Down Expand Up @@ -95,6 +101,8 @@ export const Slides = forwardRef<SlidesRef, SlidesType>((props, ref) => {
image={image}
onTap={props.onTap}
maxZoom={props.maxZoom}
imageRender={props.imageRender}
index={index}
onZoomChange={zoom => {
if (zoom !== 1) {
const index: number = Math.round(x.get() / slideWidth)
Expand Down
Loading