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

feat(ImageViewer): 底层图片渲染使用 Image #5790

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,9 @@ exports[`ConfigProvider should display the text as en 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="Image"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -2304,7 +2306,9 @@ exports[`ConfigProvider should display the text as es 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="Imagen"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -3522,7 +3526,9 @@ exports[`ConfigProvider should display the text as fa-IR 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="تصویر"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -4740,7 +4746,9 @@ exports[`ConfigProvider should display the text as fr-FR 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="Image"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -5958,7 +5966,9 @@ exports[`ConfigProvider should display the text as id-ID 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="gambar"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -7176,7 +7186,9 @@ exports[`ConfigProvider should display the text as ja-JP 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="画像"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -8394,7 +8406,9 @@ exports[`ConfigProvider should display the text as kk-KZ 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="Сурет"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -9612,7 +9626,9 @@ exports[`ConfigProvider should display the text as ko-KR 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="영상"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -10830,7 +10846,9 @@ exports[`ConfigProvider should display the text as zh-CH 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="图片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -12048,7 +12066,9 @@ exports[`ConfigProvider should display the text as zh-HK 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="圖片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -13266,7 +13286,9 @@ exports[`ConfigProvider should display the text as zh-TW 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="圖片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ exports[`ImageUploader \`preview\` & \`onPreview\` prop 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="图片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -162,7 +164,9 @@ exports[`ImageUploader custom upload button 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="图片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -265,7 +269,9 @@ exports[`ImageUploader upload status 1`] = `
class="adm-image-uploader-cell"
>
<div
aria-label="图片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down Expand Up @@ -338,7 +344,9 @@ exports[`ImageUploader upload status 1`] = `
class="adm-image-uploader-cell adm-image-uploader-cell-fail"
>
<div
aria-label="图片"
class="adm-image adm-image-uploader-cell-image"
role="img"
>
<div
class="adm-image-tip"
Expand Down
4 changes: 4 additions & 0 deletions src/components/image-viewer/demos/demo1.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.imageWidth {
--adm-image-height: 100px;
}

.footer {
padding: 16px;
text-align: center;
Expand Down
32 changes: 31 additions & 1 deletion src/components/image-viewer/demos/demo1.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { ImageViewer, Button } from 'antd-mobile'
import { ImageViewer, Button, DotLoading, ErrorBlock } from 'antd-mobile'
import { DemoBlock } from 'demos'
import { demoImage, demoImages } from './images'
import styles from './demo1.less'
Expand Down Expand Up @@ -27,6 +27,32 @@ const Single = () => {
)
}

// 图片能力展示
const MultiImage = () => {
const [visible, setVisible] = useState(false)
return (
<>
<Button
onClick={() => {
setVisible(true)
}}
>
显示图片
</Button>
<ImageViewer.Multi
images={demoImages}
visible={visible}
placeholder={<DotLoading color='primary' />}
fallback={<ErrorBlock status='default' />}
defaultIndex={1}
onClose={() => {
setVisible(false)
}}
/>
</>
)
}

// 多张图片预览
const Multi = () => {
const [visible, setVisible] = useState(false)
Expand Down Expand Up @@ -102,6 +128,10 @@ export default () => {
<Multi />
</DemoBlock>

<DemoBlock title='Image 属性展示'>
<MultiImage />
</DemoBlock>

<DemoBlock title='指令式调用'>
<Button
onClick={() => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/image-viewer/image-viewer.less
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
align-items: center;
img {
display: block;
max-width: 100%;
max-height: 100%;
max-width: 100vw;
max-height: 100vh;
luckymore marked this conversation as resolved.
Show resolved Hide resolved
}
}
&-indicator {
Expand Down
24 changes: 23 additions & 1 deletion src/components/image-viewer/image-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Mask from '../mask'
import SafeArea from '../safe-area'
import { Slide } from './slide'
import { Slides, SlidesRef } from './slides'
import { ImageProps } from '../image'

const classPrefix = `adm-image-viewer`

Expand All @@ -27,12 +28,20 @@ export type ImageViewerProps = {
onClose?: () => void
afterClose?: () => void
renderFooter?: (image: string) => React.ReactNode
}
onLoad?: (
event: React.SyntheticEvent<HTMLImageElement, Event>,
index: number
) => void
} & Pick<
ImageProps,
'fit' | 'placeholder' | 'fallback' | 'lazy' | 'crossOrigin'
>

const defaultProps = {
maxZoom: 3,
getContainer: null,
visible: false,
placeholder: null,
}

export const ImageViewer: FC<ImageViewerProps> = p => {
Expand All @@ -49,7 +58,14 @@ export const ImageViewer: FC<ImageViewerProps> = p => {
<div className={`${classPrefix}-content`}>
{props.image && (
<Slide
index={0}
image={props.image}
fit={props.fit}
placeholder={props.placeholder}
fallback={props.fallback}
lazy={props.lazy}
crossOrigin={props.crossOrigin}
onLoad={props.onLoad}
onTap={() => {
props.onClose?.()
}}
Expand Down Expand Up @@ -122,6 +138,12 @@ export const MultiImageViewer = forwardRef<
defaultIndex={index}
onIndexChange={onSlideChange}
images={props.images}
fit={props.fit}
placeholder={props.placeholder}
fallback={props.fallback}
lazy={props.lazy}
crossOrigin={props.crossOrigin}
onLoad={props.onLoad}
onTap={() => {
props.onClose?.()
}}
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 @@ -22,6 +22,8 @@ You need to click on the picture to view the details and use it with the thumbna
| renderFooter | Render extra content on footer | `(image: string) => ReactNode` | - |
| visible | Whether to show or hide | `boolean` | `false` |

In addition, the following props of [Image](/components/image) are also supported: `fit` `placeholder` `fallback` `lazy` `crossOrigin`.

## ImageViewer.Multi

On the basis of `ImageViewer`, the following props have been added:
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 @@ -22,6 +22,8 @@
| renderFooter | 渲染底部额外内容 | `(image: string) => ReactNode` | - |
| visible | 是否显示 | `boolean` | `false` |

此外,还支持 [Image](/zh/components/image) 组件的 `fit` `placeholder` `fallback` `lazy` `crossOrigin` 属性。

## ImageViewer.Multi

| 属性 | 说明 | 类型 | 默认值 |
Expand Down
26 changes: 20 additions & 6 deletions src/components/image-viewer/slide.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { FC, MutableRefObject, useRef } from 'react'
import { useSpring, animated } from '@react-spring/web'
import { useSize } from 'ahooks'
import Image, { ImageProps } from '../image'
import { rubberbandIfOutOfBounds } from '../../utils/rubberband'
import { useDragAndPinch } from '../../utils/use-drag-and-pinch'
import { bound } from '../../utils/bound'
import type { Matrix } from '../../utils/matrix'
import * as mat from '../../utils/matrix'
import { ImgRef } from '../image/image'

const classPrefix = `adm-image-viewer`

Expand All @@ -15,20 +17,27 @@ type Props = {
onTap: () => void
onZoomChange?: (zoom: number) => void
dragLockRef?: MutableRefObject<boolean>
}
index: number
onLoad?: (
event: React.SyntheticEvent<HTMLImageElement, Event>,
index: number
) => void
} & Pick<
ImageProps,
'fit' | 'placeholder' | 'fallback' | 'lazy' | 'crossOrigin'
>

export const Slide: FC<Props> = props => {
const { dragLockRef, maxZoom } = props
const controlRef = useRef<HTMLDivElement>(null)
const imgRef = useRef<HTMLImageElement>(null)
const imgRef = useRef<ImgRef>(null)
const [{ matrix }, api] = useSpring(() => ({
matrix: mat.create(),
config: { tension: 200 },
}))

const controlSize = useSize(controlRef)
const imgSize = useSize(imgRef)

const imgSize = useSize(imgRef.current?.nativeElement)
const pinchLockRef = useRef(false)

const boundMatrix = (
Expand Down Expand Up @@ -226,11 +235,16 @@ export const Slide: FC<Props> = props => {
matrix,
}}
>
<img
<Image
ref={imgRef}
src={props.image}
draggable={false}
alt={props.image}
fit={props.fit}
placeholder={props.placeholder}
fallback={props.fallback}
lazy={props.lazy}
crossOrigin={props.crossOrigin}
onLoad={evt => props.onLoad?.(evt, props.index)}
/>
</animated.div>
</div>
Expand Down
17 changes: 16 additions & 1 deletion src/components/image-viewer/slides.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useSpring, animated } from '@react-spring/web'
import { Slide } from './slide'
import { convertPx } from '../../utils/convert-px'
import { bound } from '../../utils/bound'
import { ImageProps } from '../image'

const classPrefix = `adm-image-viewer`

Expand All @@ -13,7 +14,14 @@ export type SlidesType = {
maxZoom: number
defaultIndex: number
onIndexChange?: (index: number) => void
}
onLoad?: (
event: React.SyntheticEvent<HTMLImageElement, Event>,
index: number
) => void
} & Pick<
ImageProps,
'fit' | 'placeholder' | 'fallback' | 'lazy' | 'crossOrigin'
>
export type SlidesRef = {
swipeTo: (index: number, immediate?: boolean) => void
}
Expand Down Expand Up @@ -94,7 +102,14 @@ export const Slides = forwardRef<SlidesRef, SlidesType>((props, ref) => {
{props.images.map((image, index) => (
<Slide
key={index}
index={index}
image={image}
fit={props.fit}
placeholder={props.placeholder}
fallback={props.fallback}
lazy={props.lazy}
crossOrigin={props.crossOrigin}
onLoad={evt => props.onLoad?.(evt, index)}
onTap={props.onTap}
maxZoom={props.maxZoom}
onZoomChange={zoom => {
Expand Down
Loading