mirror of
https://gitee.com/openharmony/codelabs
synced 2024-11-23 06:19:52 +00:00
手势截屏(ArkTS)Codelinter整改
Signed-off-by: 13871184879 <452399386@qq.com>
This commit is contained in:
parent
a4cb917c3a
commit
de07b3ce21
@ -4,75 +4,76 @@
|
||||
|
||||
本篇Codelab基于手势处理和截屏能力,介绍了手势截屏的实现过程。样例主要包括以下功能:
|
||||
|
||||
1. 根据下滑手势调用全屏截图功能。
|
||||
2. 全屏截图,同时右下角有弹窗提示截图成功。
|
||||
3. 根据双击手势调用区域截图功能。
|
||||
4. 区域截图,通过调整选择框大小完成。
|
||||
1. 根据下滑手势调用全屏截图功能。
|
||||
2. 全屏截图,同时右下角有弹窗提示截图成功。
|
||||
3. 根据双击手势调用区域截图功能。
|
||||
4. 区域截图,通过调整选择框大小完成。
|
||||
|
||||
![](./figures/GestureScreenshot.gif)
|
||||
|
||||
### 相关概念
|
||||
|
||||
- [Canvas](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-canvas.md):画布组件,用于自定义绘制图形。
|
||||
- [CanvasRenderingContext2D对象](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md):使用RenderingContext在Canvas组件上进行绘制,绘制对象可以是矩形、文本、图片等。
|
||||
- [双击手势](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md):手指双击屏幕回调事件。
|
||||
- [手指滑动手势](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md):手指在屏幕滑动回调事件。
|
||||
- [Canvas](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-components-canvas-canvas.md):画布组件,用于自定义绘制图形。
|
||||
- [CanvasRenderingContext2D对象](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-canvasrenderingcontext2d.md):使用RenderingContext在Canvas组件上进行绘制,绘制对象可以是矩形、文本、图片等。
|
||||
- [双击手势](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-tapgesture.md):手指双击屏幕回调事件。
|
||||
- [手指滑动手势](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-gestures-pangesture.md):手指在屏幕滑动回调事件。
|
||||
|
||||
### 相关权限
|
||||
|
||||
- 本篇Codelab用到屏幕截图的能力,需要在配置文件module.json5里添加屏幕截图的权限:ohos.permission.CAPTURE\_SCREEN。
|
||||
- 本篇Codelab需要使用的screenshot为系统接口。需要使用Full SDK手动从镜像站点获取,并在DevEco Studio中替换,具体操作可参考[替换指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/full-sdk-switch-guide.md)。
|
||||
- 本篇Codelab用到屏幕截图的能力,需要在配置文件module.json5里添加屏幕截图的权限:ohos.permission.CAPTURE\_SCREEN。
|
||||
- 本篇Codelab需要使用的screenshot为系统接口。需要使用Full SDK手动从镜像站点获取,并在DevEco Studio中替换,具体操作可参考[替换指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/faqs/full-sdk-switch-guide.md)。
|
||||
- 本篇Codelab使用的部分API仅系统应用可用,需要提升应用等级为system_core。具体可参考指南[《访问控制授权申请指导》](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/accesstoken-overview.md#%E5%BA%94%E7%94%A8apl%E7%AD%89%E7%BA%A7%E8%AF%B4%E6%98%8E)。
|
||||
|
||||
## 环境搭建
|
||||
|
||||
### 软件要求
|
||||
|
||||
- [DevEco Studio](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-overview.md#%E5%B7%A5%E5%85%B7%E5%87%86%E5%A4%87)版本:DevEco Studio 3.1 Release及以上版本。
|
||||
- OpenHarmony SDK版本:API version 9及以上版本。
|
||||
- [DevEco Studio](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-overview.md#%E5%B7%A5%E5%85%B7%E5%87%86%E5%A4%87)版本:DevEco Studio 3.1 Release。
|
||||
- OpenHarmony SDK版本:API version 9。
|
||||
|
||||
### 硬件要求
|
||||
|
||||
- 开发板类型:[润和RK3568开发板](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-appendix-rk3568.md)。
|
||||
- OpenHarmony系统:3.2 Release及以上版本。
|
||||
- 开发板类型:[润和RK3568开发板](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-appendix-rk3568.md)。
|
||||
- OpenHarmony系统:3.2 Release。
|
||||
|
||||
### 环境搭建
|
||||
|
||||
完成本篇Codelab我们首先要完成开发环境的搭建,本示例以**RK3568**开发板为例,参照以下步骤进行:
|
||||
|
||||
1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制)。以3.2 Release版本为例:
|
||||
1. [获取OpenHarmony系统版本](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md#%E8%8E%B7%E5%8F%96%E6%96%B9%E5%BC%8F3%E4%BB%8E%E9%95%9C%E5%83%8F%E7%AB%99%E7%82%B9%E8%8E%B7%E5%8F%96):标准系统解决方案(二进制)。以3.2 Release版本为例:
|
||||
|
||||
![](figures/zh-cn_image_0000001569303293.png)
|
||||
|
||||
2. 搭建烧录环境。
|
||||
1. [完成DevEco Device Tool的安装](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-ide-env-win.md)
|
||||
2. [完成RK3568开发板的烧录](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-ide-3568-burn.md)
|
||||
2. 搭建烧录环境。
|
||||
1. [完成DevEco Device Tool的安装](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-ide-env-win.md)
|
||||
2. [完成RK3568开发板的烧录](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-ide-3568-burn.md)
|
||||
|
||||
3. 搭建开发环境。
|
||||
1. 开始前请参考[工具准备](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-overview.md#%E5%B7%A5%E5%85%B7%E5%87%86%E5%A4%87),完成DevEco Studio的安装和开发环境配置。
|
||||
2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ets-stage.md#创建ets工程)创建工程(模板选择“Empty Ability”)。
|
||||
3. 工程创建完成后,选择使用[真机进行调测](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ets-stage.md#使用真机运行应用)。
|
||||
3. 搭建开发环境。
|
||||
1. 开始前请参考[工具准备](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-overview.md#%E5%B7%A5%E5%85%B7%E5%87%86%E5%A4%87),完成DevEco Studio的安装和开发环境配置。
|
||||
2. 开发环境配置完成后,请参考[使用工程向导](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ets-stage.md#创建ets工程)创建工程(模板选择“Empty Ability”)。
|
||||
3. 工程创建完成后,选择使用[真机进行调测](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/quick-start/start-with-ets-stage.md#使用真机运行应用)。
|
||||
|
||||
## 代码结构解读
|
||||
|
||||
本篇Codelab只对核心代码进行讲解,对于完整代码,我们会在gitee中提供。
|
||||
|
||||
```
|
||||
├──entry/src/main/ets // 代码区
|
||||
├──entry/src/main/ets // 代码区
|
||||
│ ├──common
|
||||
│ │ └──utils
|
||||
│ │ ├──CommonConstants.ets // 公共常量类
|
||||
│ │ ├──DrawUtil.ets // 画布相关工具类
|
||||
│ │ └──Logger.ets // 日志打印类
|
||||
│ │ └──Logger.ets // 日志打印类
|
||||
│ ├──entryability
|
||||
│ │ └──EntryAbility.ts // 程序入口类
|
||||
│ │ └──EntryAbility.ets // 程序入口类
|
||||
│ ├──model
|
||||
│ │ └──OffsetModel.ets // 区域截图坐标相关工具类
|
||||
│ ├──pages
|
||||
│ │ └──Index.ets // 主界面
|
||||
│ │ └──GestureScreenshot.ets // 主界面
|
||||
│ └──view
|
||||
│ ├──AreaScreenshot.ets // 自定义区域截屏组件类
|
||||
│ └──ScreenshotDialog.ets // 自定义截屏显示弹窗组件类
|
||||
└──entry/src/main/resources // 资源文件目录
|
||||
└──entry/src/main/resources // 资源文件目录
|
||||
```
|
||||
|
||||
## 构建截屏主页面
|
||||
@ -83,9 +84,9 @@
|
||||
|
||||
主界面主要实现以下功能:
|
||||
|
||||
1. 下滑手势绑定在主界面上,双击手势绑定在区域手势的最底层Stack组件上。
|
||||
2. 如果使用下滑手势,就进行全屏截图并展示图片。
|
||||
3. 如果使用双击手势,就唤起区域截图相关组件。
|
||||
1. 下滑手势绑定在主界面上,双击手势绑定在区域手势的最底层Stack组件上。
|
||||
2. 如果使用下滑手势,就进行全屏截图并展示图片。
|
||||
3. 如果使用双击手势,就唤起区域截图相关组件。
|
||||
|
||||
```typescript
|
||||
// GestureScreenshot.ets
|
||||
@ -95,45 +96,47 @@ Stack() {
|
||||
Column() {
|
||||
...
|
||||
})
|
||||
// 添加滑动手势事件
|
||||
.gesture(
|
||||
// fingers:触发手指数 direction:触发方向 distance:触发滑动距离
|
||||
PanGesture({ fingers: 1, direction: PanDirection.Down, distance: CommonConstants.MINIMUM_FINGER_DISTANCE })
|
||||
// 触发开始回调
|
||||
.onActionStart(() => {
|
||||
let ScreenshotOptions = {
|
||||
rotation: 0
|
||||
};
|
||||
screenshot.save(ScreenshotOptions, (err, data: image.PixelMap) => {
|
||||
if (err) {
|
||||
Logger.error(`Failed to save the screenshot. Error:${ JSON.stringify(err) }`);
|
||||
}
|
||||
if (this.pixelMap !== undefined) {
|
||||
this.pixelMap.release();
|
||||
}
|
||||
this.pixelMap = data;
|
||||
this.dialogController.open();
|
||||
});
|
||||
})
|
||||
)
|
||||
.scale(this.scaleNum)
|
||||
|
||||
// 区域截图相关组件
|
||||
AreaScreenshot({ showScreen: $showScreen, pixelMap: $pixelMap, scaleNum: $scaleNum });
|
||||
}
|
||||
.backgroundColor($r('app.color.black_area'))
|
||||
// 添加双击手势事件
|
||||
// 添加滑动手势事件
|
||||
.gesture(
|
||||
TapGesture({ count: 2 })
|
||||
.onAction(() => {
|
||||
this.showScreen = true;
|
||||
this.scaleNum = {
|
||||
x: CommonConstant.X_SCALE_DOWN,
|
||||
y: CommonConstant.Y_SCALE_DOWN
|
||||
}
|
||||
// fingers:触发手指数 direction:触发方向 distance:触发滑动距离
|
||||
PanGesture({
|
||||
fingers: 1,
|
||||
direction: PanDirection.Down,
|
||||
distance: CommonConstants.MINIMUM_FINGER_DISTANCE
|
||||
})// 触发开始回调
|
||||
.onActionStart(() => {
|
||||
let screenshotOptions: screenshot.ScreenshotOptions = {
|
||||
rotation: 0
|
||||
};
|
||||
screenshot.save(screenshotOptions, (err: Error, data: image.PixelMap) => {
|
||||
if (err) {
|
||||
Logger.error(`Failed to save the screenshot. Error:${ JSON.stringify(err) }`);
|
||||
}
|
||||
if (this.pixelMap !== undefined) {
|
||||
this.pixelMap.release();
|
||||
}
|
||||
this.pixelMap = data;
|
||||
this.dialogController.open();
|
||||
});
|
||||
})
|
||||
)
|
||||
.scale(this.scaleNum)
|
||||
|
||||
// 区域截图相关组件
|
||||
AreaScreenshot({ showScreen: this.showScreen, pixelMap: this.pixelMap, scaleNum: this.scaleNum })
|
||||
}
|
||||
.backgroundColor($r('app.color.black_area'))
|
||||
// 添加双击手势事件
|
||||
.gesture(
|
||||
TapGesture({ count: 2 })
|
||||
.onAction(() => {
|
||||
this.showScreen = true;
|
||||
this.scaleNum = {
|
||||
x: CommonConstants.X_SCALE_DOWN,
|
||||
y: CommonConstants.Y_SCALE_DOWN
|
||||
}
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
## 构建区域截图组件
|
||||
@ -152,7 +155,7 @@ aboutToAppear() {
|
||||
let property = window.getWindowProperties();
|
||||
this.systemBarHeight = property.windowRect.top;
|
||||
|
||||
drawMUtil.initDrawUtil(
|
||||
drawUtil.initDrawUtil(
|
||||
this.canvasRenderingContext,
|
||||
px2vp(property.windowRect.width),
|
||||
px2vp(property.windowRect.height)
|
||||
@ -166,7 +169,7 @@ aboutToAppear() {
|
||||
// 在展示截图的时候,用于计算图片大小
|
||||
this.screenAspectRatio = px2vp(property.windowRect.height) / px2vp(property.windowRect.width);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: Error) => {
|
||||
Logger.error(`window loading has error: ${ JSON.stringify(err) }`);
|
||||
})
|
||||
}
|
||||
@ -174,11 +177,11 @@ aboutToAppear() {
|
||||
|
||||
在AreaScreenshot.ets布局页面中添加Canvas组件,通过showScreen变量控制局部截屏页面的显示,并控制主页面的缩放。步骤如下:
|
||||
|
||||
1. 根据手指按下的位置确定需要移动的边框。
|
||||
2. 手指移动后,更新offsetModel记录的坐标信息。
|
||||
3. 根据offsetModel提供的坐标,使用drawUtil绘制区域选择框。
|
||||
4. 点击保存按钮后,设置截屏区域坐标。
|
||||
5. 根据截屏区域坐标进行区域截屏。
|
||||
1. 根据手指按下的位置确定需要移动的边框。
|
||||
2. 手指移动后,更新offsetModel记录的坐标信息。
|
||||
3. 根据offsetModel提供的坐标,使用drawUtil绘制区域选择框。
|
||||
4. 点击保存按钮后,设置截屏区域坐标。
|
||||
5. 根据截屏区域坐标进行区域截屏。
|
||||
|
||||
```typescript
|
||||
// AreaScreenshot.ets
|
||||
@ -207,23 +210,23 @@ if (this.showScreen) {
|
||||
// 区域截图并展示图像
|
||||
Image($r('app.media.ic_save'))
|
||||
.onClick(() => {
|
||||
let ScreenshotOptions = {
|
||||
let screenshotOptions: screenshot.ScreenshotOptions = {
|
||||
// 截屏区域Rect参数
|
||||
screenRect: {
|
||||
left: vp2px(offsetModel.getXLeft()),
|
||||
top: vp2px(offsetModel.getYTop()) + this.systemBarHeight,
|
||||
width: vp2px(offsetModel.getWidth()),
|
||||
height: vp2px(offsetModel.getHeight())
|
||||
},
|
||||
} as screenshot.Rect,
|
||||
// 截图的大小
|
||||
imageSize: {
|
||||
width: vp2px(offsetModel.getWidth()),
|
||||
height: vp2px(offsetModel.getHeight())
|
||||
},
|
||||
} as screenshot.Size,
|
||||
rotation: 0,
|
||||
displayId: 0
|
||||
};
|
||||
screenshot.save(ScreenshotOptions, (err, data: image.PixelMap) => {
|
||||
screenshot.save(screenshotOptions, (err: Error, data: image.PixelMap) => {
|
||||
if (err) {
|
||||
Logger.error(`Failed to save the screenshot. Error:${JSON.stringify(err)}`);
|
||||
}
|
||||
@ -243,8 +246,8 @@ if (this.showScreen) {
|
||||
switch(event.type) {
|
||||
case TouchType.Down:
|
||||
// 根据手指位置,判断移动哪个坐标
|
||||
this.offsetModel.setXLocationType(event.touches[0].screenX);
|
||||
this.offsetModel.setYLocationType(event.touches[0].screenY);
|
||||
offsetModel.setXLocationType(event.touches[0].screenX);
|
||||
offsetModel.setYLocationType(event.touches[0].screenY);
|
||||
break;
|
||||
case TouchType.Move:
|
||||
// 更新坐标信息,并保证坐标值合法
|
||||
@ -264,14 +267,14 @@ if (this.showScreen) {
|
||||
|
||||
使用OffsetModel校验坐标的范围,并保存坐标相关信息。
|
||||
|
||||
1. 在初始化对象的时候,根据屏幕的缩放比例计算出黑色区域的宽高。
|
||||
2. 使用setXLocationType方法和setYLocationType方法,判断需要移动的x、y坐标位置。
|
||||
3. 根据传入的x、y坐标值,更改offset对应的坐标值,并保证选择框的宽高大于等于预设的选择框的最小值。
|
||||
4. 再次校验offset坐标值,是否超出可截屏区域。
|
||||
1. 在初始化对象的时候,根据屏幕的缩放比例计算出黑色区域的宽高。
|
||||
2. 使用setXLocationType方法和setYLocationType方法,判断需要移动的x、y坐标位置。
|
||||
3. 根据传入的x、y坐标值,更改offset对应的坐标值,并保证选择框的宽高大于等于预设的选择框的最小值。
|
||||
4. 再次校验offset坐标值,是否超出可截屏区域。
|
||||
|
||||
```typescript
|
||||
// OffsetModel.ets
|
||||
constructor(width: number, height: number) {
|
||||
public initOffsetModel(width: number, height: number) {
|
||||
...
|
||||
this.blackAreaWidth = this.screenWidth * (1 - CommonConstant.X_SCALE_DOWN);
|
||||
this.blackAreaWidth = this.blackAreaWidth / CommonConstant.BLACK_AREA_NUM;
|
||||
@ -374,9 +377,7 @@ private drawLines() {
|
||||
(this.offsetXLeft - Constants.GAP_WIDTH),
|
||||
(this.offsetYTop + Constants.LINES_MAX_LENGTH)
|
||||
);
|
||||
|
||||
...
|
||||
|
||||
this.canvasContext.stroke();
|
||||
}
|
||||
```
|
||||
@ -385,24 +386,26 @@ private drawLines() {
|
||||
|
||||
本篇Codelab采用弹窗组件展示截屏,需要在aboutToAppear方法中计算对应的宽度:
|
||||
|
||||
1. 截图长宽比小于或者等于屏幕长宽比:此截图展示时和全屏截图展示时等宽。
|
||||
2. 截图长宽比大于屏幕长宽比:此截图展示时和全屏截图展示时等长,通过计算对应的宽来实现。
|
||||
1. 截图长宽比小于或者等于屏幕长宽比:此截图展示时和全屏截图展示时等宽。
|
||||
2. 截图长宽比大于屏幕长宽比:此截图展示时和全屏截图展示时等长,通过计算对应的宽来实现。
|
||||
|
||||
```typescript
|
||||
// ScreenShot.ets
|
||||
// ScreenshotDialog.ets
|
||||
aboutToAppear() {
|
||||
this.getDialogWidth();
|
||||
}
|
||||
...
|
||||
private async getDialogWidth() {
|
||||
let info = await this.pixelMap.getImageInfo();
|
||||
let pixelMapAspectRatio = info.size.height / info.size.width;
|
||||
if (this.pixelMap !== undefined) {
|
||||
let info = await this.pixelMap.getImageInfo();
|
||||
let pixelMapAspectRatio = info.size.height / info.size.width;
|
||||
|
||||
if ((this.screenAspectRatio !== -1) && (pixelMapAspectRatio > this.screenAspectRatio)) {
|
||||
let width = CommonConstants.HEIGHT_FIRST / pixelMapAspectRatio * this.screenAspectRatio;
|
||||
this.dialogWidth = width + '%';
|
||||
} else {
|
||||
this.dialogWidth = CommonConstants.WIDTH_FIRST;
|
||||
if ((this.screenAspectRatio !== -1) && (pixelMapAspectRatio > this.screenAspectRatio)) {
|
||||
let width = CommonConstants.HEIGHT_FIRST / pixelMapAspectRatio * this.screenAspectRatio;
|
||||
this.dialogWidth = width + '%';
|
||||
} else {
|
||||
this.dialogWidth = CommonConstants.WIDTH_FIRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -411,8 +414,8 @@ private async getDialogWidth() {
|
||||
|
||||
您已经完成了本次Codelab的学习,并了解到以下知识点:
|
||||
|
||||
1. 使用Canvas绘制区域选择框。
|
||||
2. 使用手势事件。
|
||||
3. 进行全屏截图和区域截图。
|
||||
1. 使用Canvas绘制区域选择框。
|
||||
2. 使用手势事件。
|
||||
3. 进行全屏截图和区域截图。
|
||||
|
||||
![](figures/zh-cn_image_0000001580558789.gif)
|
||||
|
@ -13,10 +13,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
interface XLocationEnumInterface {
|
||||
XLeft: number,
|
||||
XRight: number,
|
||||
noChange: number
|
||||
}
|
||||
|
||||
interface YLocationEnumInterface {
|
||||
YTop: number,
|
||||
YBottom: number,
|
||||
noChange: number
|
||||
}
|
||||
|
||||
/**
|
||||
* The x location to be changed.
|
||||
*/
|
||||
export const XLocationEnum = {
|
||||
export const XLocationEnum: XLocationEnumInterface = {
|
||||
XLeft: 0,
|
||||
XRight: 1,
|
||||
noChange: -1
|
||||
@ -25,12 +37,17 @@ export const XLocationEnum = {
|
||||
/**
|
||||
* The y location to be changed.
|
||||
*/
|
||||
export const YLocationEnum = {
|
||||
export const YLocationEnum: YLocationEnumInterface = {
|
||||
YTop: 0,
|
||||
YBottom: 1,
|
||||
noChange: -1
|
||||
}
|
||||
|
||||
export interface ScaleInterface {
|
||||
x: number,
|
||||
y: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Common constants for project.
|
||||
*/
|
||||
|
@ -20,7 +20,8 @@ import offsetModel from '../../model/OffsetModel';
|
||||
export class DrawUtil {
|
||||
private screenWidth: number = 0;
|
||||
private screenHeight: number = 0;
|
||||
private canvasContext: CanvasRenderingContext2D;
|
||||
private settings: RenderingContextSettings = new RenderingContextSettings(true);
|
||||
private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
|
||||
private offsetXLeft: number = 0;
|
||||
private offsetXRight: number = 0;
|
||||
private offsetYTop: number = 0;
|
||||
|
@ -31,19 +31,19 @@ class Logger {
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
debug(...args: any[]): void {
|
||||
debug(...args: string[]): void {
|
||||
hilog.debug(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
info(...args: any[]): void {
|
||||
info(...args: string[]): void {
|
||||
hilog.info(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
warn(...args: any[]): void {
|
||||
warn(...args: string[]): void {
|
||||
hilog.warn(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
|
||||
error(...args: any[]): void {
|
||||
error(...args: string[]): void {
|
||||
hilog.error(this.domain, this.prefix, this.format, args);
|
||||
}
|
||||
}
|
||||
|
@ -18,19 +18,18 @@ import image from '@ohos.multimedia.image';
|
||||
import AreaScreenshot from '../view/AreaScreenshot';
|
||||
import Logger from '../common/utils/Logger';
|
||||
import ScreenshotDialog from '../view/ScreenshotDialog';
|
||||
import CommonConstant from '../common/utils/CommonConstaint';
|
||||
import CommonConstants from '../common/utils/CommonConstaint';
|
||||
import { ScaleInterface } from '../common/utils/CommonConstaint';
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct GestureScreenshot {
|
||||
@State pixelMap: image.PixelMap = undefined;
|
||||
@State pixelMap: image.PixelMap| undefined = undefined;
|
||||
@State showScreen: boolean = false;
|
||||
@State scaleNum: Object = {
|
||||
x: CommonConstant.NO_SCALE_DOWN,
|
||||
y: CommonConstant.NO_SCALE_DOWN
|
||||
@State scaleNum: ScaleInterface = {
|
||||
x: CommonConstants.NO_SCALE_DOWN,
|
||||
y: CommonConstants.NO_SCALE_DOWN
|
||||
};
|
||||
|
||||
dialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: ScreenshotDialog({ pixelMap: this.pixelMap }),
|
||||
alignment: DialogAlignment.BottomEnd,
|
||||
@ -42,7 +41,7 @@ struct GestureScreenshot {
|
||||
Column() {
|
||||
Text($r('app.string.title_content'))
|
||||
.fontSize($r('app.float.title_font_size'))
|
||||
.fontWeight(CommonConstant.TITLE_FONT_WEIGHT)
|
||||
.fontWeight(CommonConstants.TITLE_FONT_WEIGHT)
|
||||
.width(CommonConstants.FULL_PARAM)
|
||||
.textAlign(TextAlign.Start)
|
||||
Image($r('app.media.ic_mountain'))
|
||||
@ -56,24 +55,27 @@ struct GestureScreenshot {
|
||||
.lineHeight($r('app.float.text_height'))
|
||||
}
|
||||
.backgroundColor($r('app.color.main_area'))
|
||||
.width(CommonConstant.FULL_PARAM)
|
||||
.height(CommonConstant.FULL_PARAM)
|
||||
.width(CommonConstants.FULL_PARAM)
|
||||
.height(CommonConstants.FULL_PARAM)
|
||||
.padding({
|
||||
left: $r('app.float.main_margin_size'),
|
||||
right: $r('app.float.main_margin_size')
|
||||
})
|
||||
.gesture(
|
||||
// fingers:The number of Trigger Fingers,direction:Triggering direction,distance:Trigger sliding distance.
|
||||
PanGesture({ fingers: 1, direction: PanDirection.Down, distance: CommonConstants.MINIMUM_FINGER_DISTANCE })
|
||||
// Trigger Start Callback.
|
||||
PanGesture({
|
||||
fingers: 1,
|
||||
direction: PanDirection.Down,
|
||||
distance: CommonConstants.MINIMUM_FINGER_DISTANCE
|
||||
})// Trigger Start Callback.
|
||||
.onActionStart(() => {
|
||||
// Screenshot Parameters and APIs.
|
||||
let ScreenshotOptions = {
|
||||
let screenshotOptions: screenshot.ScreenshotOptions = {
|
||||
rotation: 0
|
||||
};
|
||||
screenshot.save(ScreenshotOptions, (err, data: image.PixelMap) => {
|
||||
screenshot.save(screenshotOptions, (err: Error, data: image.PixelMap) => {
|
||||
if (err) {
|
||||
Logger.error(`Failed to save the screenshot. Error:${ JSON.stringify(err) }`);
|
||||
Logger.error(`Failed to save the screenshot. Error:${JSON.stringify(err)}`);
|
||||
}
|
||||
if (this.pixelMap !== undefined) {
|
||||
this.pixelMap.release();
|
||||
@ -85,7 +87,7 @@ struct GestureScreenshot {
|
||||
)
|
||||
.scale(this.scaleNum)
|
||||
|
||||
AreaScreenshot({ showScreen: $showScreen, pixelMap: $pixelMap, scaleNum: $scaleNum })
|
||||
AreaScreenshot({ showScreen: this.showScreen, pixelMap: this.pixelMap, scaleNum: this.scaleNum })
|
||||
}
|
||||
.backgroundColor($r('app.color.black_area'))
|
||||
.gesture(
|
||||
@ -93,8 +95,8 @@ struct GestureScreenshot {
|
||||
.onAction(() => {
|
||||
this.showScreen = true;
|
||||
this.scaleNum = {
|
||||
x: CommonConstant.X_SCALE_DOWN,
|
||||
y: CommonConstant.Y_SCALE_DOWN
|
||||
x: CommonConstants.X_SCALE_DOWN,
|
||||
y: CommonConstants.Y_SCALE_DOWN
|
||||
}
|
||||
})
|
||||
)
|
||||
|
@ -21,6 +21,7 @@ import ScreenshotDialog from './ScreenshotDialog';
|
||||
import drawUtil from '../common/utils/DrawUtil';
|
||||
import offsetModel from '../model/OffsetModel';
|
||||
import CommonConstants from '../common/utils/CommonConstaint';
|
||||
import { ScaleInterface } from '../common/utils/CommonConstaint';
|
||||
|
||||
/**
|
||||
* Custom component to determine the screenshot area.
|
||||
@ -29,7 +30,7 @@ import CommonConstants from '../common/utils/CommonConstaint';
|
||||
export default struct AreaScreenShot {
|
||||
@Link showScreen: boolean;
|
||||
@Link pixelMap: image.PixelMap;
|
||||
@Link scaleNum: Object;
|
||||
@Link scaleNum: ScaleInterface;
|
||||
private screenAspectRatio: number = 0;
|
||||
dialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: ScreenshotDialog({
|
||||
@ -62,8 +63,8 @@ export default struct AreaScreenShot {
|
||||
|
||||
this.screenAspectRatio = px2vp(property.windowRect.height) / px2vp(property.windowRect.width);
|
||||
})
|
||||
.catch((err) => {
|
||||
Logger.error(`window loading has error: ${ JSON.stringify(err) }`);
|
||||
.catch((err: Error) => {
|
||||
Logger.error(`window loading has error: ${JSON.stringify(err)}`);
|
||||
})
|
||||
}
|
||||
|
||||
@ -105,21 +106,21 @@ export default struct AreaScreenShot {
|
||||
|
||||
Image($r('app.media.ic_save'))
|
||||
.onClick(() => {
|
||||
let ScreenshotOptions = {
|
||||
let screenshotOptions: screenshot.ScreenshotOptions = {
|
||||
screenRect: {
|
||||
left: vp2px(offsetModel.getXLeft()),
|
||||
top: vp2px(offsetModel.getYTop()) + this.systemBarHeight,
|
||||
width: vp2px(offsetModel.getWidth()),
|
||||
height: vp2px(offsetModel.getHeight())
|
||||
},
|
||||
} as screenshot.Rect,
|
||||
imageSize: {
|
||||
width: vp2px(offsetModel.getWidth()),
|
||||
height: vp2px(offsetModel.getHeight())
|
||||
},
|
||||
} as screenshot.Size,
|
||||
rotation: 0,
|
||||
displayId: 0
|
||||
};
|
||||
screenshot.save(ScreenshotOptions, (err, data: image.PixelMap) => {
|
||||
screenshot.save(screenshotOptions, (err: Error, data: image.PixelMap) => {
|
||||
if (err) {
|
||||
Logger.error(`Failed to save the screenshot. Error:${JSON.stringify(err)}`);
|
||||
}
|
||||
@ -141,7 +142,7 @@ export default struct AreaScreenShot {
|
||||
.height(CommonConstants.FULL_PARAM)
|
||||
.alignContent(Alignment.Top)
|
||||
.onTouch((event: TouchEvent) => {
|
||||
switch(event.type) {
|
||||
switch (event.type) {
|
||||
case TouchType.Down:
|
||||
offsetModel.setXLocationType(event.touches[0].screenX);
|
||||
offsetModel.setYLocationType(event.touches[0].screenY);
|
||||
|
@ -19,7 +19,7 @@ import CommonConstants from '../common/utils/CommonConstaint';
|
||||
export default struct ScreenshotDialog {
|
||||
@State dialogWidth: string = CommonConstants.WIDTH_FIRST;
|
||||
controller: CustomDialogController;
|
||||
private pixelMap: PixelMap = null;
|
||||
private pixelMap?: PixelMap;
|
||||
private screenAspectRatio: number = -1;
|
||||
|
||||
aboutToAppear() {
|
||||
@ -38,7 +38,7 @@ export default struct ScreenshotDialog {
|
||||
.width(CommonConstants.FULL_PARAM)
|
||||
.justifyContent(FlexAlign.End)
|
||||
Row() {
|
||||
Image(this.pixelMap)
|
||||
Image(this.pixelMap !== undefined ? this.pixelMap : '')
|
||||
.width(CommonConstants.IMAGE_ON_DIALOG)
|
||||
.margin(CommonConstants.IMAGE_MARGIN)
|
||||
.objectFit(ImageFit.Contain)
|
||||
@ -54,14 +54,16 @@ export default struct ScreenshotDialog {
|
||||
}
|
||||
|
||||
private async getDialogWidth() {
|
||||
let info = await this.pixelMap.getImageInfo();
|
||||
let pixelMapAspectRatio = info.size.height / info.size.width;
|
||||
if (this.pixelMap !== undefined) {
|
||||
let info = await this.pixelMap.getImageInfo();
|
||||
let pixelMapAspectRatio = info.size.height / info.size.width;
|
||||
|
||||
if ((this.screenAspectRatio !== -1) && (pixelMapAspectRatio > this.screenAspectRatio)) {
|
||||
let width = CommonConstants.HEIGHT_FIRST / pixelMapAspectRatio * this.screenAspectRatio;
|
||||
this.dialogWidth = width + '%';
|
||||
} else {
|
||||
this.dialogWidth = CommonConstants.WIDTH_FIRST;
|
||||
if ((this.screenAspectRatio !== -1) && (pixelMapAspectRatio > this.screenAspectRatio)) {
|
||||
let width = CommonConstants.HEIGHT_FIRST / pixelMapAspectRatio * this.screenAspectRatio;
|
||||
this.dialogWidth = width + '%';
|
||||
} else {
|
||||
this.dialogWidth = CommonConstants.WIDTH_FIRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
"abilities": [
|
||||
{
|
||||
"name": "EntryAbility",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ts",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||
"description": "$string:EntryAbility_desc",
|
||||
"icon": "$media:icon",
|
||||
"label": "$string:app_name",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"hvigorVersion": "2.1.1",
|
||||
"hvigorVersion": "2.4.2",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "2.1.1"
|
||||
"@ohos/hvigor-ohos-plugin": "2.4.2"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user