|
@@ -3,45 +3,164 @@ import fs from "@ohos.file.fs"
|
|
|
import CommonEventManager from '@ohos.commonEventManager'
|
|
|
import uploadInstance from '../../common/util/UploadUtil';
|
|
|
import router from '@ohos.router';
|
|
|
-import fileIo from '@ohos.file.fs';
|
|
|
+import { DrawingInfo, DrawingPage } from '../../viewmodel/DrawingInfo';
|
|
|
+import CommonConstants from '../../common/constants/CommonConstants';
|
|
|
+import ProcessRequest from '../../common/util/request/ProcessRequest';
|
|
|
+import RequestParamModel from '../../viewmodel/RequestParamModel';
|
|
|
+import { ConfirmDialogParams } from '../../viewmodel/ConfirmDialogParam';
|
|
|
+import { CommonConfirmDialog } from '../ConfirmDialog';
|
|
|
+import promptAction from '@ohos.promptAction';
|
|
|
+
|
|
|
const TAG = "Process camera upload"
|
|
|
+
|
|
|
@Component
|
|
|
export struct MultiMediaCollect {
|
|
|
+ private scrollerPhoto: Scroller = new Scroller()
|
|
|
+ //
|
|
|
@State isExpanded: boolean = false
|
|
|
- @State selectedIndex:number = 0
|
|
|
+ //闪光模式 0:自动 1:开启 2:关闭
|
|
|
+ @State selectedFlashMode:number = 0
|
|
|
+ @State selectedPhotoIndex:number = -1
|
|
|
@State shootButtonClick:number =1
|
|
|
+ @State rotateAngle: number = 0 // 旋转角度
|
|
|
+ @State scaleValue: number = 1 // 缩放比例
|
|
|
+ @State offsetX: number = 0 // X轴偏移
|
|
|
+ @State offsetY: number = 0 // Y轴偏移
|
|
|
+ @State lastScale: number = 1 // 上次缩放值
|
|
|
+ @State lastOffsetX: number = 0 // 上次X偏移
|
|
|
+ @State lastOffsetY: number = 0 // 上次Y偏移
|
|
|
|
|
|
@State isUploading: boolean = false
|
|
|
+ @State photoList:DrawingInfo[]=[]
|
|
|
@State commodityPixelMap: PixelMap | null = null;
|
|
|
+ @State pixelMap: PixelMap | null = null;
|
|
|
@State isButtonPressed: boolean = false;
|
|
|
@State isCapturing: boolean = false;
|
|
|
@State isStopView: boolean = false;
|
|
|
@State reminds:string = ''
|
|
|
@State readTimer:number = 0
|
|
|
- private previewManager: PreviewManager | null = null; // 初始化为 null
|
|
|
+ private previewManager: PreviewManager | null = null;
|
|
|
|
|
|
subscriber: CommonEventManager.CommonEventSubscriber | null = null;
|
|
|
subscribeInfo: CommonEventManager.CommonEventSubscribeInfo = { events: ["sonycamera_callback"] };
|
|
|
- //订阅回调(code=1代表连接成功,code=2代表拍照成功)
|
|
|
+
|
|
|
+ commonDialogController: CustomDialogController | null = null;
|
|
|
+ private showConfirmDialog(params: ConfirmDialogParams) {
|
|
|
+ if (this.commonDialogController) {
|
|
|
+ this.commonDialogController.close()
|
|
|
+ }
|
|
|
+
|
|
|
+ this.commonDialogController = new CustomDialogController({
|
|
|
+ builder: CommonConfirmDialog({
|
|
|
+ title: params.title || '提示',
|
|
|
+ message: params.message,
|
|
|
+ confirmText: params.confirmText || '确定',
|
|
|
+ cancelText: params.cancelText || '取消',
|
|
|
+ onConfirm: params.onConfirm
|
|
|
+ }),
|
|
|
+ cancel: () => console.log('用户取消操作'),
|
|
|
+ customStyle: true,
|
|
|
+ autoCancel:false,
|
|
|
+ maskColor: 'rgba(0,0,0,0.6)'
|
|
|
+ });
|
|
|
+
|
|
|
+ this.commonDialogController.open();
|
|
|
+ }
|
|
|
+ //订阅回调(code=3代表连接成功,code=2代表拍照成功)
|
|
|
createSubscriber = async () => {
|
|
|
this.subscriber = await CommonEventManager.createSubscriber(this.subscribeInfo);
|
|
|
if (this.subscriber) {
|
|
|
- console.info(TAG,"创建订阅回调成功");
|
|
|
+ console.info(TAG, "创建订阅回调成功");
|
|
|
CommonEventManager.subscribe(this.subscriber, (err, data) => {
|
|
|
if (err?.code) {
|
|
|
- console.error(TAG,"SubscribeCallBack err=" + JSON.stringify(err));
|
|
|
- } else {
|
|
|
- console.info(TAG,"SubscribeCallBack data=" + JSON.stringify(data));
|
|
|
- if (data && data.code&&data.code === 2) {
|
|
|
- this.uploadPhoto();//拍照成功->上传照片
|
|
|
- }else if (data && data.code&&data.code === 3) {
|
|
|
- console.info(TAG,"开始预览" );
|
|
|
- this.startView();//连接成功开始预览
|
|
|
+ console.error(TAG, "SubscribeCallBack err=" + JSON.stringify(err));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.info(TAG, "SubscribeCallBack data=" + JSON.stringify(data));
|
|
|
+ if (data?.code !== undefined) {
|
|
|
+ switch (data.code) {
|
|
|
+ case 2:
|
|
|
+ this.uploadPhoto(); // 拍照成功
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ console.info(TAG, "开始预览");
|
|
|
+ this.startView(); // 连接成功
|
|
|
+ break;
|
|
|
+ case -1:
|
|
|
+ console.info(TAG,'连接故障')
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ console.info(TAG,'暂停预览')
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //0001:自动闪光 0002:关闭闪光 0003:开启闪光
|
|
|
+ if (data?.parameters?.flash_mode) {
|
|
|
+ const flashMode:string = data.parameters.flash_mode
|
|
|
+ console.info(TAG, `收到闪光模式: ${flashMode}`);
|
|
|
+ switch (flashMode) {
|
|
|
+ case '0001':
|
|
|
+ this.selectedFlashMode = 0
|
|
|
+ break;
|
|
|
+ case '0002':
|
|
|
+ this.selectedFlashMode = 2
|
|
|
+ break;
|
|
|
+ case '0003':
|
|
|
+ this.selectedFlashMode = 1
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ console.warn(TAG, `未知闪光模式: ${flashMode}`);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
};
|
|
|
+
|
|
|
+ //加载照片
|
|
|
+ loadPhotos=async()=>{
|
|
|
+ let res = await ProcessRequest.post('/api/v1/process/media/page', {
|
|
|
+ } as RequestParamModel) as DrawingPage;
|
|
|
+ this.photoList=res.records??[]
|
|
|
+ }
|
|
|
+
|
|
|
+ //删除照片
|
|
|
+ deletePhoto=async(photoId:string)=>{
|
|
|
+ let res = await ProcessRequest.post('/api/v1/process/media/del', {
|
|
|
+ id: photoId
|
|
|
+ } as RequestParamModel) as DrawingPage;
|
|
|
+ this.loadPhotos()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private rotateImage(angle: number) {
|
|
|
+ this.offsetX = 0;
|
|
|
+ this.offsetY = 0;
|
|
|
+ this.rotateAngle += angle
|
|
|
+ if (this.rotateAngle >= 360) {
|
|
|
+ this.rotateAngle -= 360
|
|
|
+ } else if (this.rotateAngle < 0) {
|
|
|
+ this.rotateAngle += 360
|
|
|
+ }
|
|
|
+ if(this.rotateAngle==90||this.rotateAngle==270)
|
|
|
+ {
|
|
|
+ this.scaleValue=0.63
|
|
|
+ }else {
|
|
|
+ this.scaleValue=1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置图片变换
|
|
|
+ private resetImageTransform() {
|
|
|
+ this.rotateAngle = 0
|
|
|
+ this.scaleValue = 1
|
|
|
+ this.offsetX = 0
|
|
|
+ this.offsetY = 0
|
|
|
+ this.lastScale = 1
|
|
|
+ this.lastOffsetX = 0
|
|
|
+ this.lastOffsetY = 0
|
|
|
+ }
|
|
|
+
|
|
|
//连接相机
|
|
|
connectCamera = async () => {
|
|
|
CommonEventManager.publish("opensession", (err) => {
|
|
@@ -52,6 +171,16 @@ export struct MultiMediaCollect {
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
+ //查询闪光模式
|
|
|
+ queryFlashMode = async () => {
|
|
|
+ CommonEventManager.publish("queryflashmode", (err) => {
|
|
|
+ if (err?.code) {
|
|
|
+ console.info(TAG,"Publish openSession err=" + JSON.stringify(err))
|
|
|
+ } else {
|
|
|
+ console.info(TAG,"Publish openSession succeed ")
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
//开始预览
|
|
|
startView=()=>{
|
|
@@ -65,32 +194,48 @@ export struct MultiMediaCollect {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
- //重连相机
|
|
|
- reconnectCamera=()=>{
|
|
|
- CommonEventManager.publish("reconnect", (err) => {
|
|
|
+
|
|
|
+ //停止预览
|
|
|
+ stopView=async()=>{
|
|
|
+ CommonEventManager.publish("stopview", (err) => {
|
|
|
if (err?.code) {
|
|
|
- console.info("[CommonEvent] Publish CallBack err=" + JSON.stringify(err))
|
|
|
+ console.error(TAG, JSON.stringify(err));
|
|
|
} else {
|
|
|
- console.info("[CommonEvent] Publish reconnect succeed ")
|
|
|
- AlertDialog.show(
|
|
|
- {
|
|
|
- title: '请重新插入相机USB线缆',
|
|
|
- message: '请重新插入相机USB线缆',
|
|
|
- confirm: {
|
|
|
- value: '确定',
|
|
|
- action: () => {
|
|
|
- console.info('执行重新连接操作');
|
|
|
- router.back();
|
|
|
- // 这里可以添加重连逻辑
|
|
|
- }
|
|
|
- },
|
|
|
- cancel: () => {
|
|
|
- console.info('用户取消操作');
|
|
|
- }
|
|
|
- }
|
|
|
- )
|
|
|
+ this.isCapturing = false;
|
|
|
+ this.isStopView =true;
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //重连相机
|
|
|
+ reconnectCamera=async()=>{
|
|
|
+ this.showConfirmDialog({
|
|
|
+ title: '重连USB',
|
|
|
+ message: `请重连USB后点击确定!`,
|
|
|
+ onConfirm: async()=> {
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
+ CommonEventManager.publish("stopview", (err) => {
|
|
|
+ if (err) return reject(err);
|
|
|
+ CommonEventManager.publish("closesession", (err) => {
|
|
|
+ err ? reject(err) : resolve();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
+ CommonEventManager.publish("reconnect", (err) => {
|
|
|
+ if (err) return reject(err);
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ promptAction.showToast({
|
|
|
+ message: '相机正在重连中...',
|
|
|
+ duration: 3000,
|
|
|
+ bottom: 500
|
|
|
+ });
|
|
|
+ await sleep(3000);
|
|
|
+ await this.connectCamera()
|
|
|
+ await this.liveShow()
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
//开始预览 50ms一张图片(20帧)
|
|
@@ -177,11 +322,13 @@ export struct MultiMediaCollect {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+
|
|
|
//上传照片
|
|
|
uploadPhoto=()=>{
|
|
|
let imageUri: string = "/data/storage/el2/base/haps/entry/files/image_base64.txt"
|
|
|
try {
|
|
|
uploadInstance.startUploadBase64(imageUri, () => {
|
|
|
+ this.loadPhotos()
|
|
|
this.isUploading = false
|
|
|
this.startView();//上传完恢复预览
|
|
|
})
|
|
@@ -190,8 +337,10 @@ export struct MultiMediaCollect {
|
|
|
}
|
|
|
}
|
|
|
async aboutToAppear() {
|
|
|
+ this.loadPhotos();
|
|
|
await this.createSubscriber();
|
|
|
await this.connectCamera();
|
|
|
+ await this.queryFlashMode();
|
|
|
await this.liveShow();
|
|
|
}
|
|
|
|
|
@@ -217,10 +366,12 @@ export struct MultiMediaCollect {
|
|
|
Row() {
|
|
|
Stack(){
|
|
|
if (this.commodityPixelMap) {
|
|
|
- Image(this.commodityPixelMap)
|
|
|
- .width('100%')
|
|
|
- .height('100%')
|
|
|
- .objectFit(ImageFit.Fill)
|
|
|
+ if (this.selectedPhotoIndex === -1) {
|
|
|
+ Image(this.commodityPixelMap)
|
|
|
+ .width('100%')
|
|
|
+ .height('100%')
|
|
|
+ .objectFit(ImageFit.Fill)
|
|
|
+ }
|
|
|
}
|
|
|
if(this.isUploading){
|
|
|
Column() {
|
|
@@ -238,10 +389,11 @@ export struct MultiMediaCollect {
|
|
|
.borderRadius($r('app.float.virtualSize_16'))
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
}
|
|
|
- Row() {
|
|
|
+ if(this.selectedPhotoIndex === -1){
|
|
|
+ Row() {
|
|
|
Image(
|
|
|
- this.selectedIndex === 0 ? $r('app.media.process_flash_auto') :
|
|
|
- this.selectedIndex === 1 ? $r('app.media.process_flash_open') :
|
|
|
+ this.selectedFlashMode === 0 ? $r('app.media.process_flash_auto') :
|
|
|
+ this.selectedFlashMode === 1 ? $r('app.media.process_flash_open') :
|
|
|
$r('app.media.process_flash_close')
|
|
|
)
|
|
|
.width($r('app.float.virtualSize_48'))
|
|
@@ -256,48 +408,48 @@ export struct MultiMediaCollect {
|
|
|
Row(){
|
|
|
Text('自动')
|
|
|
.fontSize($r('app.float.fontSize_24'))
|
|
|
- .fontColor(this.selectedIndex===0?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
+ .fontColor(this.selectedFlashMode===0?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
}
|
|
|
.width('33.3%')
|
|
|
.height('100%')
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
.borderRadius($r('app.float.virtualSize_16'))
|
|
|
- .backgroundColor(this.selectedIndex===0?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
+ .backgroundColor(this.selectedFlashMode===0?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
.onClick(() => {
|
|
|
this.setFlashMode('autoflash')
|
|
|
this.isExpanded = false
|
|
|
- this.selectedIndex = 0
|
|
|
+ this.selectedFlashMode = 0
|
|
|
})
|
|
|
Row(){
|
|
|
Text('开启')
|
|
|
.fontSize($r('app.float.fontSize_24'))
|
|
|
- .fontColor(this.selectedIndex===1?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
+ .fontColor(this.selectedFlashMode===1?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
}
|
|
|
.width('33.3%')
|
|
|
.height('100%')
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
.borderRadius($r('app.float.virtualSize_16'))
|
|
|
- .backgroundColor(this.selectedIndex===1?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
+ .backgroundColor(this.selectedFlashMode===1?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
.onClick(() => {
|
|
|
this.setFlashMode('openflash')
|
|
|
this.isExpanded = false
|
|
|
- this.selectedIndex = 1
|
|
|
+ this.selectedFlashMode = 1
|
|
|
})
|
|
|
|
|
|
Row(){
|
|
|
Text('关闭')
|
|
|
.fontSize($r('app.float.fontSize_24'))
|
|
|
- .fontColor(this.selectedIndex===2?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
+ .fontColor(this.selectedFlashMode===2?$r('app.color.FFFFFF'):$r('app.color.60FFFFFF'))
|
|
|
}
|
|
|
.width('33.3%')
|
|
|
.height('100%')
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
.borderRadius($r('app.float.virtualSize_16'))
|
|
|
- .backgroundColor(this.selectedIndex===2?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
+ .backgroundColor(this.selectedFlashMode===2?$r('app.color.0A84FF'):$r('app.color.60000000'))
|
|
|
.onClick(() => {
|
|
|
this.setFlashMode('closeflash')
|
|
|
this.isExpanded = false
|
|
|
- this.selectedIndex = 2
|
|
|
+ this.selectedFlashMode = 2
|
|
|
})
|
|
|
}
|
|
|
.animation({ duration: 300, curve: Curve.EaseOut }) // 展开动画
|
|
@@ -312,7 +464,7 @@ export struct MultiMediaCollect {
|
|
|
.position({ x: '2%', y: '92%' })
|
|
|
.height('5%')
|
|
|
.width('24%')
|
|
|
- Image(this.shootButtonClick===1?$r('app.media.process_no_shoot'):$r('app.media.process_shoot'))
|
|
|
+ Image(this.shootButtonClick===1?$r('app.media.process_no_shoot'):$r('app.media.process_shoot'))
|
|
|
.width($r('app.float.virtualSize_88'))
|
|
|
.height($r('app.float.virtualSize_88'))
|
|
|
.scale({ x: this.shootButtonClick, y: this.shootButtonClick })
|
|
@@ -334,41 +486,259 @@ export struct MultiMediaCollect {
|
|
|
this.takePhoto();
|
|
|
})
|
|
|
.position({ x: '48%', y: '90%' })
|
|
|
+ Row(){
|
|
|
+ Text("重连相机")
|
|
|
+ .fontColor($r('app.color.FFFFFF'))
|
|
|
+ .fontSize($r('app.float.fontSize_24'))
|
|
|
+ }
|
|
|
+ .width('10%')
|
|
|
+ .height('6%')
|
|
|
+ .backgroundColor($r('app.color.20FFFFFF'))
|
|
|
+ .position({ x: '88%', y: '91%' })
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ .onClick(()=>{
|
|
|
+ this.reconnectCamera()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ Stack() {
|
|
|
+ Image(CommonConstants.PICTURE_URL_PREFIX + this.photoList[this.selectedPhotoIndex].filePath)
|
|
|
+ .width('100%')
|
|
|
+ .height('100%')
|
|
|
+ .objectFit(ImageFit.Fill)
|
|
|
+ .rotate({ angle: this.rotateAngle })
|
|
|
+ .scale({ x: this.scaleValue, y: this.scaleValue })
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
+ .translate({ x: this.offsetX, y: this.offsetY })
|
|
|
+ .gesture(
|
|
|
+ GestureGroup(GestureMode.Exclusive,
|
|
|
+ // 双指缩放手势
|
|
|
+ PinchGesture()
|
|
|
+ .onActionStart(() => {
|
|
|
+ this.lastScale = this.scaleValue
|
|
|
+ this.lastOffsetX = this.offsetX
|
|
|
+ this.lastOffsetY = this.offsetY
|
|
|
+ })
|
|
|
+ .onActionUpdate((event: GestureEvent) => {
|
|
|
+ this.scaleValue = this.lastScale * event.scale
|
|
|
+ })
|
|
|
+ .onActionEnd(() => {
|
|
|
+ if (this.scaleValue < 1) {
|
|
|
+ if(this.rotateAngle==90||this.rotateAngle==270) {
|
|
|
+ this.scaleValue = 0.63
|
|
|
+ } else {
|
|
|
+ this.scaleValue = 1
|
|
|
+ }
|
|
|
+ // 缩放结束后检查边界
|
|
|
+
|
|
|
+ }
|
|
|
+ if (this.scaleValue > 4) this.scaleValue = 4
|
|
|
+ }),
|
|
|
+
|
|
|
+ // 单指滑动手势
|
|
|
+ // 在PanGesture的onActionEnd中添加边界检查和回弹逻辑
|
|
|
+ PanGesture()
|
|
|
+ .onActionStart(() => {
|
|
|
+ if (this.scaleValue <= 1) return;
|
|
|
+ this.lastOffsetX = this.offsetX;
|
|
|
+ this.lastOffsetY = this.offsetY;
|
|
|
+ })
|
|
|
+ .onActionUpdate((event: GestureEvent) => {
|
|
|
+ if (this.scaleValue <= 1) return;
|
|
|
+
|
|
|
+ let dx = event.offsetX;
|
|
|
+ let dy = event.offsetY;
|
|
|
+ const sensitivity = 0.5 * this.scaleValue;
|
|
|
+
|
|
|
+ // 临时计算新位置,不直接赋值给状态变量
|
|
|
+ let newOffsetX = this.lastOffsetX;
|
|
|
+ let newOffsetY = this.lastOffsetY;
|
|
|
+
|
|
|
+ switch(this.rotateAngle % 360) {
|
|
|
+ case 0:
|
|
|
+ newOffsetX += dx * sensitivity;
|
|
|
+ newOffsetY += dy * sensitivity;
|
|
|
+ break;
|
|
|
+ case 90:
|
|
|
+ newOffsetX -= dy * sensitivity;
|
|
|
+ newOffsetY += dx * sensitivity;
|
|
|
+ break;
|
|
|
+ case 180:
|
|
|
+ newOffsetX -= dx * sensitivity;
|
|
|
+ newOffsetY -= dy * sensitivity;
|
|
|
+ break;
|
|
|
+ case 270:
|
|
|
+ newOffsetX += dy * sensitivity;
|
|
|
+ newOffsetY -= dx * sensitivity;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ this.offsetX = newOffsetX;
|
|
|
+ this.offsetY = newOffsetY;
|
|
|
+ })
|
|
|
+ .onActionEnd(() => {
|
|
|
+ if (this.scaleValue <= 1) {
|
|
|
+ // 如果缩放比例<=1,直接重置位置
|
|
|
+ this.offsetX = 0;
|
|
|
+ this.offsetY = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算最大允许偏移量(基于缩放比例)
|
|
|
+ const maxOffsetX = (this.scaleValue - 1) * 500; // 100是容器的半宽
|
|
|
+ const maxOffsetY = (this.scaleValue - 1) * 345; // 100是容器的半高
|
|
|
+
|
|
|
+ // 检查X轴边界
|
|
|
+ if (Math.abs(this.offsetX) > maxOffsetX) {
|
|
|
+ this.offsetX = this.offsetX > 0 ? maxOffsetX : -maxOffsetX;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查Y轴边界
|
|
|
+ if (Math.abs(this.offsetY) > maxOffsetY) {
|
|
|
+ this.offsetY = this.offsetY > 0 ? maxOffsetY : -maxOffsetY;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加回弹动画
|
|
|
+ animateTo({
|
|
|
+ duration: 300,
|
|
|
+ curve: Curve.EaseOut
|
|
|
+ }, () => {
|
|
|
+ // 动画结束后确保位置正确
|
|
|
+ this.offsetX = this.offsetX;
|
|
|
+ this.offsetY = this.offsetY;
|
|
|
+ });
|
|
|
+ })
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .height('100%')
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
+ .clip(true)
|
|
|
+ Row()
|
|
|
+ {
|
|
|
+ Row(){
|
|
|
+ Image($r('app.media.process_back_camera'))
|
|
|
+ .width($r('app.float.virtualSize_80'))
|
|
|
+ .height($r('app.float.virtualSize_80'))
|
|
|
+ .onClick(()=>{
|
|
|
+ this.selectedPhotoIndex=-1
|
|
|
+ this.startView()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .width('10%')
|
|
|
+ .justifyContent(FlexAlign.Start)
|
|
|
+ Row({space:20}){
|
|
|
+ Image($r("app.media.process_photo_reset"))
|
|
|
+ .width($r('app.float.virtualSize_80'))
|
|
|
+ .height($r('app.float.virtualSize_80'))
|
|
|
+ .onClick(()=>{
|
|
|
+ this.resetImageTransform()
|
|
|
+ })
|
|
|
+ Image($r('app.media.process_photo_turn_left'))
|
|
|
+ .width($r('app.float.virtualSize_80'))
|
|
|
+ .height($r('app.float.virtualSize_80'))
|
|
|
+ .onClick(()=>{
|
|
|
+ this.rotateImage(-90)
|
|
|
+ if(this.rotateAngle==90)
|
|
|
+ {
|
|
|
+ console.info("sssaaa"+this.rotateAngle)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ Image($r('app.media.process_photo_turn_right'))
|
|
|
+ .width($r('app.float.virtualSize_80'))
|
|
|
+ .height($r('app.float.virtualSize_80'))
|
|
|
+ .onClick(()=>{
|
|
|
+ this.rotateImage(90)
|
|
|
+ })
|
|
|
+ Image($r('app.media.process_photo_delete'))
|
|
|
+ .width($r('app.float.virtualSize_80'))
|
|
|
+ .height($r('app.float.virtualSize_80'))
|
|
|
+ .onClick(()=>{
|
|
|
+ this.showConfirmDialog({
|
|
|
+ title: '删除照片',
|
|
|
+ message: `确定要删除照片吗?`,
|
|
|
+ onConfirm: ()=> {
|
|
|
+ const photosNum = this.photoList.length
|
|
|
+ const photoId=this.photoList[this.selectedPhotoIndex].id
|
|
|
+ //如果是图册最后一张照片,显示前一张照片,没有照片则返回拍照页面
|
|
|
+ if(this.selectedPhotoIndex===photosNum-1)
|
|
|
+ {
|
|
|
+ this.selectedPhotoIndex--
|
|
|
+ }
|
|
|
+ this.deletePhoto(photoId)
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }.width('88%')
|
|
|
+ .justifyContent(FlexAlign.End)
|
|
|
+ .margin({right :'2%'})
|
|
|
+ }.width('98%')
|
|
|
+ .height('10%')
|
|
|
+ .position({x:'2%',y:'90%'})
|
|
|
+ }
|
|
|
}
|
|
|
- .width('80%')
|
|
|
+ .width('86%')
|
|
|
.height('100%')
|
|
|
.backgroundColor($r('app.color.000000'))
|
|
|
- .border({width:2,color:$r('app.color.10FFFFFF')})
|
|
|
+ .border({width:2})
|
|
|
+ Column(){
|
|
|
+ List({ space: 8,scroller:this.scrollerPhoto }) {
|
|
|
+ ForEach(this.photoList, (item: DrawingInfo, index) => {
|
|
|
+ ListItem() {
|
|
|
+ Column({space:4}){
|
|
|
+ Column(){
|
|
|
+ Image(CommonConstants.PICTURE_URL_PREFIX+item.filePath)
|
|
|
+ .objectFit(ImageFit.Fill)
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
+ .height('97%')
|
|
|
+ .width('98%')
|
|
|
+ .opacity(index === this.selectedPhotoIndex ? 0.8 : 1) // 20% 透明度
|
|
|
+ }
|
|
|
+ .backgroundColor(index === this.selectedPhotoIndex ? $r('app.color.30D158') : '')
|
|
|
+ .width('90%')
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ .alignItems(HorizontalAlign.Center)
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
+ .height('85%')
|
|
|
+ Text(`${item.updated}`)
|
|
|
+ .fontSize($r('app.float.fontSize_12'))
|
|
|
+ .fontColor($r('app.color.FFFFFF'))
|
|
|
+ .width('90%')
|
|
|
+ .textAlign(TextAlign.Start)
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .height('100%')
|
|
|
+ .justifyContent(FlexAlign.Start)
|
|
|
+ .alignItems(HorizontalAlign.Center)
|
|
|
+ .enabled(!this.isUploading)
|
|
|
+ .onClick(()=>{
|
|
|
+ this.selectedPhotoIndex = index;
|
|
|
+ this.resetImageTransform()
|
|
|
+ this.stopView();
|
|
|
+
|
|
|
+ })
|
|
|
+ }.height('19%')
|
|
|
+ .margin({bottom:'2%'})
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .margin({top:'2%',bottom:'2%'})
|
|
|
+ .height('96%')
|
|
|
+ }
|
|
|
+ .width('14%')
|
|
|
+ .height('100%')
|
|
|
}
|
|
|
.width('100%')
|
|
|
.height('100%')
|
|
|
- .backgroundColor($r('app.color.10FFFFFF'))
|
|
|
- .borderRadius($r('app.float.fontSize_16'))
|
|
|
+ //.backgroundColor($r('app.color.10FFFFFF'))
|
|
|
+ .borderRadius($r('app.float.virtualSize_16'))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function sleep(ms: number): Promise<void> {
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
}
|
|
|
-@CustomDialog
|
|
|
-struct RemindDialog {
|
|
|
- controller: CustomDialogController
|
|
|
- @Link remind: string
|
|
|
- build() {
|
|
|
- Column() {
|
|
|
- Text(this.remind)
|
|
|
- .fontSize(20)
|
|
|
- .margin({ top: 10, bottom: 10 })
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-function delayExecution(callback: Function, delay: number) {
|
|
|
- let timerId = setInterval(() => {
|
|
|
- clearInterval(timerId);
|
|
|
- callback();
|
|
|
- }, delay);
|
|
|
-}
|
|
|
|
|
|
class PreviewManager {
|
|
|
private context: Context;
|
|
@@ -393,8 +763,6 @@ class PreviewManager {
|
|
|
this.isProcessing = true;
|
|
|
try {
|
|
|
const filePath = `${this.context.filesDir}/live${index}.jpg`;
|
|
|
-
|
|
|
- // 检查文件是否存在
|
|
|
try {
|
|
|
fs.accessSync(filePath);
|
|
|
} catch {
|
|
@@ -407,13 +775,8 @@ class PreviewManager {
|
|
|
this.isProcessing = false;
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
- // 创建较小尺寸的PixelMap以提高性能
|
|
|
-
|
|
|
this.nextBuffer = await imageSource.createPixelMap();
|
|
|
imageSource.release();
|
|
|
-
|
|
|
- // 交换缓冲区
|
|
|
if (this.activeBuffer) {
|
|
|
this.activeBuffer.release();
|
|
|
}
|
|
@@ -445,3 +808,7 @@ class PreviewManager {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+interface CameraParam {
|
|
|
+ flash_mode: string;
|
|
|
+ moduleName?: string;
|
|
|
+}
|