import { CropController, CropView, IBestToast, YTAvoid, YTLog, yTRouter, YTUserRequest } from 'basic' import { fileIo } from '@kit.CoreFileKit' import { util } from '@kit.ArkTS' import { emitter } from '@kit.BasicServicesKit' @Builder function delPhotoPageBuilder() { NavDestination() { DelPhotoPage() } .hideTitleBar(true) } @Component struct DelPhotoPage { @StorageProp(YTAvoid.SAFE_BOTTOM_KEY) private safeBottom: number = 0 @State private selectPhoto: string = '' @State private frameWidth: number = 220 @State private frameHeight: number = 220 @State private startWidth: number = 220 @State private startHeight: number = 220 private declare type: 'bill' | 'header' | 'image' private controller: CropController = new CropController() private declare context: Context aboutToAppear(): void { this.selectPhoto = yTRouter.getDelPhotoParam().src this.type = yTRouter.getDelPhotoParam().type const tempContext = this.getUIContext().getHostContext() if (tempContext === undefined) { //抛出异常 throw new Error('DelPhotoPage context is null') } else { this.context = tempContext } YTAvoid.setStatusBarContentColor('#FFFFFFFF', this.context) } aboutToDisappear(): void { YTAvoid.setStatusBarContentColor('#FF000000', this.context) } build() { Column() { Stack({ alignContent: Alignment.Center }) { CropView({ src: this.selectPhoto, controller: this.controller, // 控制器必须设置 maskColor: '#4D000000', frameWidth: this.frameWidth, frameHeight: this.frameHeight }) .width("100%") .layoutWeight(1) .backgroundColor(Color.Black) Column() { Row() { Text() .height(30) .aspectRatio(1) .border({ width: { left: 8, top: 8 }, color: Color.White }) .offset({ x: -8, y: -8 }) .borderRadius({ topLeft: 5 }) .gesture( PanGesture({ distance: 1 }) .onActionStart(() => { // 记录拖拽开始时的初始尺寸 this.startWidth = this.frameWidth this.startHeight = this.frameHeight }) .onActionUpdate(event => { // 基于初始尺寸计算新尺寸 const newWidth = Math.max(220, this.startWidth - event.offsetX) const newHeight = Math.max(220, this.startHeight - event.offsetY) // 同时更新两个维度 this.frameWidth = newWidth this.frameHeight = newHeight }) ) Text() .height(30) .aspectRatio(1) .border({ width: { right: 8, top: 8 }, color: Color.White }) .offset({ x: 8, y: -8 }) .borderRadius({ topRight: 5 }) .gesture( PanGesture({ distance: 1 }) .onActionStart(() => { // 记录拖拽开始时的初始尺寸 this.startWidth = this.frameWidth this.startHeight = this.frameHeight }) .onActionUpdate(event => { // 基于初始尺寸计算新尺寸 const newWidth = Math.max(220, this.startWidth + event.offsetX) const newHeight = Math.max(220, this.startHeight - event.offsetY) // 同时更新两个维度 this.frameWidth = newWidth this.frameHeight = newHeight }) ) } .width('100%') .height(25) .justifyContent(FlexAlign.SpaceBetween) .borderRadius(8) Row() { Text() .height(30) .aspectRatio(1) .border({ width: { left: 8, bottom: 8 }, color: Color.White }) .offset({ x: -8, y: 8 }) .borderRadius({ bottomLeft: 5 }) .gesture( PanGesture({ distance: 1 }) .onActionStart(() => { // 记录拖拽开始时的初始尺寸 this.startWidth = this.frameWidth this.startHeight = this.frameHeight }) .onActionUpdate(event => { // 基于初始尺寸计算新尺寸 const newWidth = Math.max(220, this.startWidth - event.offsetX) const newHeight = Math.max(220, this.startHeight + event.offsetY) // 同时更新两个维度 this.frameWidth = newWidth this.frameHeight = newHeight }) ) Text() .height(30) .aspectRatio(1) .border({ width: { right: 8, bottom: 8 }, color: Color.White }) .borderRadius({ bottomRight: 5 }) .offset({ x: 8, y: 8 }) .gesture( PanGesture({ distance: 1 }) .onActionStart(() => { // 记录拖拽开始时的初始尺寸 this.startWidth = this.frameWidth this.startHeight = this.frameHeight }) .onActionUpdate(event => { // 基于初始尺寸计算新尺寸 const newWidth = Math.max(220, this.startWidth + event.offsetX) const newHeight = Math.max(220, this.startHeight + event.offsetY) // 同时更新两个维度 this.frameWidth = newWidth this.frameHeight = newHeight }) ) } .width('100%') .height(25) .justifyContent(FlexAlign.SpaceBetween) } .width(this.frameWidth) .height(this.frameHeight) .justifyContent(FlexAlign.SpaceBetween) .hitTestBehavior(HitTestMode.Transparent) } .layoutWeight(1) Row() { Image($r('app.media.back')) .width(36) .aspectRatio(1) .onClick(() => { yTRouter.routerBack() }) Image($r('app.media.make_sure')) .height(56) .aspectRatio(1) .onClick(() => { //使用 controller 获取裁剪图片 this.controller.cropWithPath({ format: 'image/jpeg', quality: 100 }) .then(async (path) => { // path 为裁剪后的文件路径 try { const photoName = util.generateRandomUUID() const photoType = '.jpeg' const fullpath = this.context.cacheDir + '/' + photoName + photoType const photo = fileIo.openSync(path) await fileIo.copyFile(photo.fd, fullpath) if (this.type == 'header') { IBestToast.showLoading({ message: '上传中...' }) YTUserRequest.uploadHeadImg(this.getUIContext().getHostContext()!, fullpath, () => { YTUserRequest.refreshUserInfo(() => { IBestToast.hide() setTimeout(() => { IBestToast.show({ message: '头像修改成功', type: 'success' }) }, 100) }) }) yTRouter.routerBack() } if (this.type == 'image') { IBestToast.showLoading({ message: '上传中...' }) YTUserRequest.uploadFile(this.getUIContext().getHostContext()!, fullpath, (url) => { emitter.emit('upLoadEnd', { data: url }) IBestToast.hide() yTRouter.routerBack() }) } } catch (e) { YTLog.error(e) } }) }) Image($r('app.media.rotate')) .height(36) .aspectRatio(1) .onClick(() => { this.controller.rotate() }) } .width('100%') .height(84) .justifyContent(FlexAlign.SpaceAround) } .padding({ bottom: this.safeBottom }) } }