Skip to content

Commit

Permalink
feat(avatarcropper): 新增属性shape,可设置裁剪样式为圆形 (#1842)
Browse files Browse the repository at this point in the history
  • Loading branch information
yi-boide authored Jan 5, 2024
1 parent b890826 commit 05a985a
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports[`layout default slot 1`] = `
/>
<input
accept="image/*"
aria-label="选择图片"
class="nut-avatar-cropper-input"
type="file"
/>
Expand Down
5 changes: 5 additions & 0 deletions src/packages/avatarcropper/avatarcropper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,9 @@
}
}
}
&.round {
.nut-avatar-cropper-edit-text {
border-radius: 50%;
}
}
}
12 changes: 11 additions & 1 deletion src/packages/avatarcropper/avatarcropper.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { clamp, preventDefault } from '@/utils'
export type AvatarCropperToolbarPosition = 'top' | 'bottom'
export type AvatarCropperSizeType = 'original' | 'compressed'
export type AvatarCropperSourceType = 'album' | 'camera'
export type AvatarCropperShape = 'square' | 'round'
export interface AvatarCropperProps extends BasicComponent {
maxZoom: number
space: number
Expand All @@ -24,6 +25,7 @@ export interface AvatarCropperProps extends BasicComponent {
editText: React.ReactNode | string
sizeType: AvatarCropperSizeType[]
sourceType: AvatarCropperSourceType[]
shape: AvatarCropperShape
onConfirm: (e: string) => void
onCancel: () => void
}
Expand All @@ -46,6 +48,7 @@ const defaultProps = {
editText: '编辑',
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
shape: 'square',
} as AvatarCropperProps

const classPrefix = `nut-avatar-cropper`
Expand All @@ -61,6 +64,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
editText,
sizeType,
sourceType,
shape,
className,
style,
onConfirm,
Expand All @@ -83,7 +87,12 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
cropperCanvasContext: Taro.CanvasContext | null
}

const cls = classNames(classPrefix, 'taro', className)
const cls = classNames(
classPrefix,
'taro',
className,
shape === 'round' && 'round'
)
const toolbarPositionCls = classNames(
`${classPrefix}-popup-toolbar`,
toolbarPosition
Expand Down Expand Up @@ -160,6 +169,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
return {
width,
height,
borderRadius: shape === 'round' ? '50%' : '',
}
}, [pixelRatio, state.cropperWidth])

Expand Down
8 changes: 7 additions & 1 deletion src/packages/avatarcropper/avatarcropper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import { clamp, preventDefault } from '@/utils'
import { getRect } from '@/utils/use-client-rect'

export type AvatarCropperToolbarPosition = 'top' | 'bottom'
export type AvatarCropperShape = 'square' | 'round'
export interface AvatarCropperProps extends BasicComponent {
maxZoom: number
space: number
toolbar: React.ReactNode[]
toolbarPosition: AvatarCropperToolbarPosition
editText: React.ReactNode | string
shape: AvatarCropperShape
onConfirm: (e: string) => void
onCancel: () => void
}
Expand All @@ -40,6 +42,7 @@ const defaultProps = {
],
toolbarPosition: 'bottom',
editText: '编辑',
shape: 'square',
} as AvatarCropperProps

const classPrefix = `nut-avatar-cropper`
Expand All @@ -53,6 +56,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
space,
toolbarPosition,
editText,
shape,
className,
style,
onConfirm,
Expand All @@ -63,7 +67,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
...props,
}

const cls = classNames(classPrefix, className)
const cls = classNames(classPrefix, className, shape === 'round' && 'round')
const toolbarPositionCls = classNames(
`${classPrefix}-popup-toolbar`,
toolbarPosition
Expand Down Expand Up @@ -109,6 +113,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
return {
width,
height,
borderRadius: shape === 'round' ? '50%' : '',
}
}, [devicePixelRatio, drawImage.swidth])

Expand Down Expand Up @@ -469,6 +474,7 @@ export const AvatarCropper: FunctionComponent<Partial<AvatarCropperProps>> = (
accept="image/*"
className={`${classPrefix}-input`}
onChange={(e: any) => inputImageChange(e)}
aria-label="选择图片"
/>
<div className="nut-avatar-cropper-edit-text">{editText}</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions src/packages/avatarcropper/demo.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ import './demo.scss'
interface T {
c0a1c0a1: string
c0a1c0a2: string
c0a1c0a3: string
}
const AvatarCropperDemo = () => {
const [translated] = useTranslate<T>({
'zh-CN': {
c0a1c0a1: '基础用法',
c0a1c0a2: '自定义裁剪区域工具栏',
c0a1c0a3: '圆形裁剪',
},
'zh-TW': {
c0a1c0a1: '基礎用法',
c0a1c0a2: '自定義裁剪區域工具欄',
c0a1c0a3: '圓形裁剪',
},
'en-US': {
c0a1c0a1: 'Basic usage',
c0a1c0a2: 'Customize the cropping area toolbar',
c0a1c0a3: 'Roll Finger Cutting',
},
})
const [imageUrl, setImageUrl] = useState(
Expand Down Expand Up @@ -70,6 +74,12 @@ const AvatarCropperDemo = () => {
<Avatar size="large" src={imageUrl} />
</AvatarCropper>
</Cell>
<h2>{translated.c0a1c0a3}</h2>
<Cell>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</Cell>
</div>
</>
)
Expand Down
10 changes: 10 additions & 0 deletions src/packages/avatarcropper/demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ import './demo.scss'
interface T {
c0a1c0a1: string
c0a1c0a2: string
c0a1c0a3: string
}
const AvatarCropperDemo = () => {
const [translated] = useTranslate<T>({
'zh-CN': {
c0a1c0a1: '基础用法',
c0a1c0a2: '自定义裁剪区域工具栏',
c0a1c0a3: '圆形裁剪',
},
'zh-TW': {
c0a1c0a1: '基礎用法',
c0a1c0a2: '自定義裁剪區域工具欄',
c0a1c0a3: '圓形裁剪',
},
'en-US': {
c0a1c0a1: 'Basic usage',
c0a1c0a2: 'Customize the cropping area toolbar',
c0a1c0a3: 'Roll Finger Cutting',
},
})
const [imageUrl, setImageUrl] = useState(
Expand Down Expand Up @@ -59,6 +63,12 @@ const AvatarCropperDemo = () => {
<Avatar size="large" src={imageUrl} />
</AvatarCropper>
</Cell>
<h2>{translated.c0a1c0a3}</h2>
<Cell>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</Cell>
</div>
</>
)
Expand Down
31 changes: 31 additions & 0 deletions src/packages/avatarcropper/doc.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ export default App;

:::

### Roll Finger Cutting

Set the shape of the crop display, which is still square after the crop, and need to set rounded corners in the display place

:::demo

```tsx
import React, { useState } from "react";
import { Avatar, AvatarCropper } from '@nutui/nutui-react';

const App = () => {
const [imageUrl, setImageUrl] = useState(
'https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png'
)
const cutImage = (data: any) => {
setImageUrl(data)
}
return (
<>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</>
)
}
export default App;
```

:::

## AvatarCropper

### Props
Expand All @@ -98,5 +128,6 @@ export default App;
| edit-text | The text content in the middle | `ReactNode \| string` | `编辑` |
| toolbar | Customize the clipping area toolbar, after setting this content | `ReactNode[]` | `[<Button type="danger" key="cancel">取消</Button>, <Button type="info" key="reset">重置</Button>,<Button type="warning" key="rotate">旋转</Button>,<Button type="success" key="confirm">确认</Button>]` |
| toolbar-position | Location of the toolbar in the clipping area. The optional value is:`top` `bottom` | `string` | `bottom` |
| shape | Crop shape, optional value is:`square` `round` | `string` | `square` |
| onConfirm | Click Confirm to trigger after cropping | `(url: string) => void` | `-` |
| onCancel | Click cancel trigger | `-` | `-` |
31 changes: 31 additions & 0 deletions src/packages/avatarcropper/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ export default App;

:::

### 圆形裁剪

设置裁剪展示的形状,裁剪后还是方形的,需要在展示的地方设置圆角

:::demo

```tsx
import React, { useState } from "react";
import { Avatar, AvatarCropper } from '@nutui/nutui-react';

const App = () => {
const [imageUrl, setImageUrl] = useState(
'https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png'
)
const cutImage = (data: any) => {
setImageUrl(data)
}
return (
<>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</>
)
}
export default App;
```

:::

## AvatarCropper

### Props
Expand All @@ -98,5 +128,6 @@ export default App;
| editText | 中间的文字内容 | `ReactNode \| string` | `编辑` |
| toolbar | 自定义裁剪区域工具栏 | `ReactNode[]` | `[<Button type="danger" key="cancel">取消</Button>, <Button type="info" key="reset">重置</Button>,<Button type="warning" key="rotate">旋转</Button>,<Button type="success" key="confirm">确认</Button>]` |
| toolbarPosition | 裁剪区域工具栏位置,可选值为:`top` `bottom` | `string` | `bottom` |
| shape | 裁剪形状,可选值为:`square` `round` | `string` | `square` |
| onConfirm | 裁剪后点击确认触发 | `(url: string) => void` | `-` |
| onCancel | 点击取消触发 | `-` | `-` |
31 changes: 31 additions & 0 deletions src/packages/avatarcropper/doc.taro.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ export default App;

:::

### 圆形裁剪

设置裁剪展示的形状,裁剪后还是方形的,需要在展示的地方设置圆角

:::demo

```tsx
import React, { useState } from "react";
import { Avatar, AvatarCropper } from '@nutui/nutui-react';

const App = () => {
const [imageUrl, setImageUrl] = useState(
'https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png'
)
const cutImage = (data: any) => {
setImageUrl(data)
}
return (
<>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</>
)
}
export default App;
```

:::

## AvatarCropper

### Props
Expand All @@ -100,5 +130,6 @@ export default App;
| source-type | 选择图片的来源: 可选值:`album` `camera` | `Array` | `['album', 'camera']` |
| toolbar | 自定义裁剪区域工具栏 | `ReactNode[]` | `[<Button type="danger" key="cancel">取消</Button>, <Button type="info" key="reset">重置</Button>,<Button type="warning" key="rotate">旋转</Button>,<Button type="success" key="confirm">确认</Button>]` |
| toolbarPosition | 裁剪区域工具栏位置,可选值为:`top` `bottom` | `string` | `bottom` |
| shape | 裁剪形状,可选值为:`square` `round` | `string` | `square` |
| onConfirm | 裁剪后点击确认触发 | `(url: string) => void` | `-` |
| onCancel | 点击取消触发 | `-` | `-` |
31 changes: 31 additions & 0 deletions src/packages/avatarcropper/doc.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ export default App;

:::

### 圓形裁剪

設置裁剪展示的形狀,裁剪後還是方形的,需要在展示的地方設置圓角

:::demo

```tsx
import React, { useState } from "react";
import { Avatar, AvatarCropper } from '@nutui/nutui-react';

const App = () => {
const [imageUrl, setImageUrl] = useState(
'https://img12.360buyimg.com/imagetools/jfs/t1/196430/38/8105/14329/60c806a4Ed506298a/e6de9fb7b8490f38.png'
)
const cutImage = (data: any) => {
setImageUrl(data)
}
return (
<>
<AvatarCropper shape="round" onConfirm={cutImage}>
<Avatar size="large" shape="round" src={imageUrl} />
</AvatarCropper>
</>
)
}
export default App;
```

:::

## AvatarCropper

### Props
Expand All @@ -98,5 +128,6 @@ export default App;
| toolbarPosition | 裁剪區域工具欄位置,可選值為:`top` `bottom` | `string` | `bottom` |
| editText | 中間的文字內容 | `ReactNode \| string` | `編輯` |
| toolbar | 自定義裁剪區域工具欄 | `ReactNode[]` | `[<Button type="danger" key="cancel">取消</Button>, <Button type="info" key="reset">重置</Button>,<Button type="warning" key="rotate">旋转</Button>,<Button type="success" key="confirm">确认</Button>]` |
| shape | 裁剪形狀,可選值爲:`square` `round` | `string` | `square` |
| onConfirm | 裁剪後點擊確認觸發 | `(url: string) => void` | `-` |
| onCancel | 點擊取消觸發 | `-` | `-` |
1 change: 1 addition & 0 deletions src/packages/avatarcropper/index.taro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export type {
AvatarCropperToolbarPosition,
AvatarCropperSizeType,
AvatarCropperSourceType,
AvatarCropperShape,
} from './avatarcropper.taro'
export default AvatarCropper
1 change: 1 addition & 0 deletions src/packages/avatarcropper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { AvatarCropper } from './avatarcropper'
export type {
AvatarCropperProps,
AvatarCropperToolbarPosition,
AvatarCropperShape,
} from './avatarcropper'
export default AvatarCropper

0 comments on commit 05a985a

Please sign in to comment.