From 70bea3229b467ac6d436333b6e2128dcb42205d9 Mon Sep 17 00:00:00 2001
From: zhounie <2676178337@qq.com>
Date: Sun, 7 Dec 2025 14:23:36 +0800
Subject: [PATCH] =?UTF-8?q?docs:=20react-native-image-crop-picker=E6=94=AF?=
=?UTF-8?q?=E6=8C=81cropperCircleOverlay=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: zhounie <2676178337@qq.com>
---
en/react-native-image-crop-picker.md | 116 ++++++++++++++++++++---
zh-cn/react-native-image-crop-picker.md | 120 +++++++++++++++++++++---
2 files changed, 208 insertions(+), 28 deletions(-)
diff --git a/en/react-native-image-crop-picker.md b/en/react-native-image-crop-picker.md
index aec26ebc..341f6886 100644
--- a/en/react-native-image-crop-picker.md
+++ b/en/react-native-image-crop-picker.md
@@ -64,6 +64,7 @@ const ImageCropPickDemo = () => {
const [writeTempFile, setTempFile] = React.useState(true);
const [includeBase64, setBase64] = React.useState(false);
const [freeStyleCropEnabled, setFreeStyleCropEnabled] = React.useState(false);
+ const [cropperCircleOverlay, setCropperCircleOverlay] = React.useState(false);
const [forceJpg, setForceJpg] = React.useState(false);
const [showsSelectedCount, setShowsSelectedCount] = React.useState(true);
const [selectedButton, setSelectedButton] = React.useState('any');
@@ -539,6 +540,16 @@ const ImageCropPickDemo = () => {
+
+
+ cropperCircleOverlay :
+
+
compressImageQuality:
{
freeStyleCropEnabled: freeStyleCropEnabledCropper,
compressImageQuality: imageQualityCropper,
forceJpg: forceJpgCropper,
+ cropperCircleOverlay: cropperCircleOverlay,
cropperToolbarTitle: cropperTitle,
cropperChooseText: chooseText,
cropperChooseColor: chooseColor,
@@ -913,8 +925,70 @@ export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
```
### 2.5. Configuration Entry
+**(1)Change EntryAbility.ets under entry/src/main/ets/entryability**
+
+```
+import {RNAbility} from '@rnoh/react-native-openharmony';
+import { AbilityConstant, Want } from '@kit.AbilityKit';
+import window from '@ohos.window';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+const DOMAIN = 0x0000;
-**(1)Create ImageEditAbility.ets under entry/src/main/ets/entryability**
+export default class EntryAbility extends RNAbility {
+
+ onCreate(want: Want) {
+ super.onCreate(want)
+ }
+
+ getPagePath() {
+ return 'pages/Index';
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err) => {
+
+ let windowClass: window.Window = windowStage.getMainWindowSync()
+ let isLayoutFullScreen = true
+ windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
+ console.info('Succeeded in setting the window layout to full-screen mode.')
+ }).catch((err: BusinessError) => {
+ console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`)
+ })
+
+ let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
+ let avoidArea = windowClass.getWindowAvoidArea(type);
+ let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航区域的高度
+ AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
+
+ type = window.AvoidAreaType.TYPE_SYSTEM;
+ avoidArea = windowClass.getWindowAvoidArea(type);
+ let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
+ AppStorage.setOrCreate('topRectHeight', topRectHeight);
+
+ windowClass.on('avoidAreaChange', (data) => {
+ if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
+ let topRectHeight = data.area.topRect.height;
+ AppStorage.setOrCreate('topRectHeight', topRectHeight);
+ } else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
+ let bottomRectHeight = data.area.bottomRect.height;
+ AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
+ }
+ });
+
+ if (err.code) {
+ hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
+ return;
+ }
+ hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
+ });
+ }
+}
+```
+
+**(2)Create ImageEditAbility.ets under entry/src/main/ets/entryability**
```
import UIAbility from '@ohos.app.ability.UIAbility'
@@ -963,7 +1037,7 @@ export default class ImageEditAbility extends UIAbility {
}
```
-**(2)Register ImageEditAbility in entry/src/main/module.json5.**
+**(3)Register ImageEditAbility in entry/src/main/module.json5.**
```
"abilities":[
@@ -982,28 +1056,42 @@ export default class ImageEditAbility extends UIAbility {
```
-**(3)Create entry/src/main/ets/pages under ImageEdit.ets**
+**(4)Create entry/src/main/ets/pages under ImageEdit.ets**
```
import { ImageEditInfo } from '@react-native-ohos/react-native-image-crop-picker';
+import { CircleImageInfo } from '@react-native-ohos/react-native-image-crop-picker';
@Entry
@Component
struct ImageEdit {
-
- build() {
- Row(){
- Column(){
- ImageEditInfo();
- }
- .width('100%')
+ @State cropperCircleOverlay: boolean = false;
+ @StorageProp('bottomRectHeight')
+ bottomRectHeight: number = 0;
+ @StorageProp('topRectHeight')
+ topRectHeight: number = 0;
+
+ build() {
+ Row() {
+ Column() {
+ if(!this.cropperCircleOverlay){
+ ImageEditInfo()
+ } else {
+ CircleImageInfo()
+ }
+ }
+ .width('100%')
+ .padding({
+ top: this.getUIContext().px2vp(this.topRectHeight),
+ bottom: this.getUIContext().px2vp(this.bottomRectHeight)
+ })
+ }
+ .height('100%')
}
- .height('100%')
- }
}
```
-**(4)Add configuration in entry/src/main/resources/base/profile/main_pages.json**
+**(5)Add configuration in entry/src/main/resources/base/profile/main_pages.json**
```
{
@@ -1075,7 +1163,7 @@ RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK;IDE: DevEco Studio 6.0.0.868;RO
| cropperToolbarWidgetColor (Android only) | string (default `darker orange`) | When cropping image, determines the color of Toolbar text and buttons. | no | Android | no |
| freeStyleCropEnabled | bool (default false) | Enables user to apply custom rectangle area for cropping | no | All | yes |
| cropperToolbarTitle | string (default `Edit Photo`) | When cropping image, determines the title of Toolbar. | no | All | yes |
-| cropperCircleOverlay | bool (default false) | Enable or disable circular cropping mask. | no | All | no |
+| cropperCircleOverlay | bool (default false) | Enable or disable circular cropping mask. | no | All | yes |
| disableCropperColorSetters (Android only) | bool (default false) | When cropping image, disables the color setters for cropping library. | no | Android | no |
| minFiles (iOS only) | number (default 1) | Min number of files to select when using `multiple` option | no | iOS | no |
| maxFiles (iOS only) | number (default 5) | Max number of files to select when using `multiple` option | no | iOS | yes |
diff --git a/zh-cn/react-native-image-crop-picker.md b/zh-cn/react-native-image-crop-picker.md
index fcf5dc80..49fea55c 100644
--- a/zh-cn/react-native-image-crop-picker.md
+++ b/zh-cn/react-native-image-crop-picker.md
@@ -64,6 +64,7 @@ const ImageCropPickDemo = () => {
const [writeTempFile, setTempFile] = React.useState(true);
const [includeBase64, setBase64] = React.useState(false);
const [freeStyleCropEnabled, setFreeStyleCropEnabled] = React.useState(false);
+ const [cropperCircleOverlay, setCropperCircleOverlay] = React.useState(false);
const [forceJpg, setForceJpg] = React.useState(false);
const [showsSelectedCount, setShowsSelectedCount] = React.useState(true);
const [selectedButton, setSelectedButton] = React.useState('any');
@@ -539,6 +540,16 @@ const ImageCropPickDemo = () => {
+
+
+ cropperCircleOverlay :
+
+
compressImageQuality:
{
freeStyleCropEnabled: freeStyleCropEnabledCropper,
compressImageQuality: imageQualityCropper,
forceJpg: forceJpgCropper,
+ cropperCircleOverlay: cropperCircleOverlay,
cropperToolbarTitle: cropperTitle,
cropperChooseText: chooseText,
cropperChooseColor: chooseColor,
@@ -912,7 +924,70 @@ export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
### 2.5. 配置Entry
-**(1)在 entry/src/main/ets/entryability 下创建 ImageEditAbility.ets**
+**(1)在 entry/src/main/ets/entryability 下修改 EntryAbility.ets**
+
+```
+import {RNAbility} from '@rnoh/react-native-openharmony';
+import { AbilityConstant, Want } from '@kit.AbilityKit';
+import window from '@ohos.window';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+const DOMAIN = 0x0000;
+
+export default class EntryAbility extends RNAbility {
+
+ onCreate(want: Want) {
+ super.onCreate(want)
+ }
+
+ getPagePath() {
+ return 'pages/Index';
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err) => {
+
+ let windowClass: window.Window = windowStage.getMainWindowSync()
+ let isLayoutFullScreen = true
+ windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
+ console.info('Succeeded in setting the window layout to full-screen mode.')
+ }).catch((err: BusinessError) => {
+ console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`)
+ })
+
+ let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
+ let avoidArea = windowClass.getWindowAvoidArea(type);
+ let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航区域的高度
+ AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
+
+ type = window.AvoidAreaType.TYPE_SYSTEM;
+ avoidArea = windowClass.getWindowAvoidArea(type);
+ let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
+ AppStorage.setOrCreate('topRectHeight', topRectHeight);
+
+ windowClass.on('avoidAreaChange', (data) => {
+ if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
+ let topRectHeight = data.area.topRect.height;
+ AppStorage.setOrCreate('topRectHeight', topRectHeight);
+ } else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
+ let bottomRectHeight = data.area.bottomRect.height;
+ AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
+ }
+ });
+
+ if (err.code) {
+ hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
+ return;
+ }
+ hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
+ });
+ }
+}
+```
+
+**(2)在 entry/src/main/ets/entryability 下创建 ImageEditAbility.ets**
```
import UIAbility from '@ohos.app.ability.UIAbility'
@@ -961,7 +1036,7 @@ export default class ImageEditAbility extends UIAbility {
}
```
-**(2)在 entry/src/main/module.json5 注册 ImageEditAbility**
+**(3)在 entry/src/main/module.json5 注册 ImageEditAbility**
```
"abilities":[
@@ -980,28 +1055,45 @@ export default class ImageEditAbility extends UIAbility {
```
-**(3)在 entry/src/main/ets/pages 下创建 ImageEdit.ets**
+**(4)在 entry/src/main/ets/pages 下创建 ImageEdit.ets**
```
import { ImageEditInfo } from '@react-native-ohos/react-native-image-crop-picker';
-
+import { CircleImageInfo } from '@react-native-ohos/react-native-image-crop-picker';
@Entry
@Component
struct ImageEdit {
+ @State cropperCircleOverlay: boolean = false;
+ @StorageProp('bottomRectHeight')
+ bottomRectHeight: number = 0;
+ @StorageProp('topRectHeight')
+ topRectHeight: number = 0;
+
+ aboutToAppear(): void {
+ this.cropperCircleOverlay = AppStorage.Get('cropperCircleOverlay') || false
+ }
- build() {
- Row(){
- Column(){
- ImageEditInfo();
- }
- .width('100%')
+ build() {
+ Row() {
+ Column() {
+ if(!this.cropperCircleOverlay){
+ ImageEditInfo()
+ } else {
+ CircleImageInfo()
+ }
+ }
+ .width('100%')
+ .padding({
+ top: this.getUIContext().px2vp(this.topRectHeight),
+ bottom: this.getUIContext().px2vp(this.bottomRectHeight)
+ })
+ }
+ .height('100%')
}
- .height('100%')
- }
}
```
-**(4)在 entry/src/main/resources/base/profile/main_pages.json 添加配置**
+**(5)在 entry/src/main/resources/base/profile/main_pages.json 添加配置**
```
{
@@ -1073,7 +1165,7 @@ RNOH:0.77.18; SDK:HarmonyOS 6.0.0 Release SDK;IDE:DevEco Studio 6.0.0.8
| cropperToolbarWidgetColor (Android only) | string (default `darker orange`) | 裁剪图片时,指定工具栏文本和按钮的颜色。 | no | Android | no |
| freeStyleCropEnabled | bool (default false) | 允许用户自定义裁剪区域的矩形范围 | no | All | yes |
| cropperToolbarTitle | string (default `Edit Photo`) | 裁剪图片时,指定工具栏的标题。 | no | All | yes |
-| cropperCircleOverlay | bool (default false) | 启用或禁用圆形裁剪遮罩。 | no | All | no |
+| cropperCircleOverlay | bool (default false) | 启用或禁用圆形裁剪遮罩。 | no | All | yes |
| disableCropperColorSetters (Android only) | bool (default false) | 裁剪图片时,禁用裁剪库的颜色设置功能。 | no | Android | no |
| minFiles (iOS only) | number (default 1) | 启用 `multiple` 选项时,最少选择的文件数量 | no | iOS | no |
| maxFiles (iOS only) | number (default 5) | 启用 `multiple` 选项时,最多选择的文件数量 | no | iOS | yes |
--
Gitee