Skip to content

Commit

Permalink
Merge pull request #2815 from xiamiao1121/feature/preview/#2808
Browse files Browse the repository at this point in the history
feat(preview): 支持配置图片水印以及禁止右键下载图片
  • Loading branch information
solarjoker authored May 10, 2024
2 parents 428f8d0 + e133da0 commit c4f48c1
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/large-glasses-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/preview": minor
---

feat: 支持配置图片水印以及禁止右键下载图片
5 changes: 5 additions & 0 deletions .changeset/serious-penguins-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hi-ui/hiui": patch
---

feat(preview): 支持图片配置水印以及禁止右键下载图片
49 changes: 39 additions & 10 deletions packages/ui/preview/src/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { forwardRef, useCallback, useState, useEffect, useRef, useMemo }
import { cx, getPrefixCls } from '@hi-ui/classname'
import { __DEV__ } from '@hi-ui/env'
import { Portal } from '@hi-ui/portal'
import { Watermark, WatermarkProps } from '@hi-ui/watermark'
import { CSSTransition } from 'react-transition-group'
import { useUncontrolledState } from '@hi-ui/use-uncontrolled-state'
import { HiBaseHTMLProps } from '@hi-ui/core'
Expand Down Expand Up @@ -43,6 +44,8 @@ export const Preview = forwardRef<HTMLDivElement | null, PreviewProps>(
onError,
onClose,
src,
watermarkProps,
disabledDownload = false,
},
ref
) => {
Expand All @@ -65,6 +68,13 @@ export const Preview = forwardRef<HTMLDivElement | null, PreviewProps>(

const isMultiple = useMemo(() => Array.isArray(src) && src.length > 1, [src])

// 图片加水印
const [watermarkContainerRef, setWatermarkContainerRef] = useState<HTMLDivElement | null>(null)

const handleContextMenu = useLatestCallback((evt: React.MouseEvent) => {
evt.preventDefault()
})

// 重置图片
const resetTransform = useCallback(() => {
updateImgTransform(defaultTransform)
Expand Down Expand Up @@ -226,20 +236,28 @@ export const Preview = forwardRef<HTMLDivElement | null, PreviewProps>(
onMouseMove={onMoving}
onKeyDown={handleKeyDown}
>
<img
ref={imgRef}
onLoad={() => {
setIsLoaded(true)
<div
className={`${prefixCls}__img-wrapper`}
ref={(e) => {
setWatermarkContainerRef(e)
}}
onError={onError}
onMouseDown={onMoveStart}
onMouseUp={onMoveEnd}
src={Array.isArray(src) ? src[active] : src}
className={`${prefixCls}__image`}
style={{
transform: `scale(${imgTransform.scale}, ${imgTransform.scale}) translate(${imgTransform.translateX}px,${imgTransform.translateY}px) rotate(${imgTransform.rotate}deg)`,
}}
/>
>
<img
ref={imgRef}
onLoad={() => {
setIsLoaded(true)
}}
onError={onError}
onMouseDown={onMoveStart}
onMouseUp={onMoveEnd}
onContextMenu={disabledDownload ? handleContextMenu : undefined}
src={Array.isArray(src) ? src[active] : src}
className={`${prefixCls}__image`}
/>
</div>
<div className={`${prefixCls}__toolbar`}>
<ZoomInOutlined
onClick={() => {
Expand Down Expand Up @@ -286,6 +304,9 @@ export const Preview = forwardRef<HTMLDivElement | null, PreviewProps>(
</>
)}
</div>
{watermarkProps && (
<Watermark {...watermarkProps} container={watermarkContainerRef} />
)}
</>
)}
</div>
Expand Down Expand Up @@ -315,6 +336,14 @@ export interface PreviewProps extends Omit<HiBaseHTMLProps<'div'>, 'onError'> {
* 当前预览图片索引
*/
defaultCurrent?: number
/**
* 设置图片水印
*/
watermarkProps?: Omit<WatermarkProps, 'container'>
/**
* 是否禁止右键下载图片
*/
disabledDownload?: boolean
/**
* 加载错误回调
*/
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/preview/src/styles/preview.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,8 @@ $prefix: '#{$component-prefix}-preview' !default;
pointer-events: auto;
display: inline-block;
}

&__img-wrapper {
display: inline-block;
}
}
51 changes: 51 additions & 0 deletions packages/ui/preview/stories/banned.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import Preview from '../src'
import Grid from '@hi-ui/grid'

/**
* @title 禁止右键下载
*/
export const Banned = () => {
const [showIndex, setShowIndex] = React.useState(-1)
const [images] = React.useState([
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_1.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_2.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_3.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_4.png',
])

return (
<>
<h1>Banned</h1>
<div className="preview-banned__wrap">
<Preview
title={`pic_${showIndex}.png`}
src={images[showIndex]}
visible={showIndex !== -1}
disabledDownload={true}
onClose={() => {
setShowIndex(-1)
}}
/>

<Grid.Row gutter={true}>
{images.map((url, index) => {
return (
<Grid.Col span={4} key={index}>
<div>
<img
src={url}
style={{ width: '100%', cursor: 'pointer' }}
onClick={() => {
setShowIndex(index)
}}
/>
</div>
</Grid.Col>
)
})}
</Grid.Row>
</div>
</>
)
}
2 changes: 2 additions & 0 deletions packages/ui/preview/stories/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Preview from '../src'

export * from './basic.stories'
export * from './multiple.stories'
export * from './watermark.stories'
export * from './banned.stories'

export default {
title: 'Data Display/Preview',
Expand Down
62 changes: 62 additions & 0 deletions packages/ui/preview/stories/watermark.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react'
import Preview from '../src'
import Grid from '@hi-ui/grid'

/**
* @title 添加水印
*/
export const Watermark = () => {
const [showIndex, setShowIndex] = React.useState(-1)
const [images] = React.useState([
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_1.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_2.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_3.png',
'http://i1.mifile.cn/f/i/hiui/docs/card/pic_4.png',
])

return (
<>
<h1>Watermark</h1>
<div className="preview-watermark__wrap">
<Preview
title={`pic_${showIndex}.png`}
src={images[showIndex]}
visible={showIndex !== -1}
onClose={() => {
setShowIndex(-1)
}}
watermarkProps={{
content: ['HiUI', '做中台,就用 HiUI'],
style: {
pointerEvents: 'none',
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
left: 0,
zIndex: 2048,
},
}}
/>

<Grid.Row gutter={true}>
{images.map((url, index) => {
return (
<Grid.Col span={4} key={index}>
<div>
<img
src={url}
style={{ width: '100%', cursor: 'pointer' }}
onClick={() => {
setShowIndex(index)
}}
/>
</div>
</Grid.Col>
)
})}
</Grid.Row>
</div>
</>
)
}

0 comments on commit c4f48c1

Please sign in to comment.