HarmonyOS matrix实现图像平移缩放,效果很差,能否提供对应高效能demo

HarmonyOS matrix实现图像平移缩放,效果很差,能否提供对应高效能demo

HarmonyOS
2024-08-10 13:10:47
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

PinchGestureExample文件

import { ImageViewModel as ImageModel } from './ImageModel' 
import { componentUtils, ComponentUtils, matrix4 } from '@kit.ArkUI' 
import display from '@ohos.display' 
 
// xxx.ets 
@Entry 
@Component 
struct PinchGestureExample { 
  @State imageModel: ImageModel = new ImageModel() 
  @StorageProp('windowRatio') windowRatio: number = 1 
  @StorageProp('windowWidthVp') windowWidthVp: number = 0 
  @StorageProp('windowHeightVp') windowHeightVp: number = 0 
  @State ratio: number = 1 
  @State src: ResourceStr = $r('app.media.startIcon') 
  @State imageInitialX: number = 0 
  @State imageInitialY: number = 0 
 
  aboutToAppear() { 
    display.getAllDisplays((err, data) => { 
      this.windowWidthVp = data[0].width 
      this.windowHeightVp = data[0].height 
      console.log('width = ' + this.windowWidthVp + 'screenHeight = ' + this.windowHeightVp) 
    }) 
  } 
 
  build() { 
    Navigation() { 
      Stack() { 
        // 笔记层 
        Column() { 
          Row() { 
            Button('Back') 
            Button('Share') 
          } 
          .width('100%') 
          .height(50) 
          .justifyContent(FlexAlign.SpaceBetween) 
 
          Divider() 
            .strokeWidth(0.5) 
            .color(0x14000000) 
 
          Scroll() { 
            Column() { 
              // 模拟轮播图 
              // todo: 图片渲染完成后获取一次初始位置保存下来 
              Image(this.src) 
                .objectFit(ImageFit.Contain) 
                .width('100%') 
                .constraintSize({ maxHeight: 400 }) 
                .onComplete((res: Record<string, Object>) => { 
                  this.ratio = (res.width as number) / (res.height as number) 
                })/*.scale({ 
                  x: this.imageModel.curScale, 
                  y: this.imageModel.curScale 
                })// 捏合触发该手势事件*/ 
                .gesture( 
                  PinchGesture() 
                    .onActionStart((event: GestureEvent) => { 
                      // this.imageModel.imageSrc = $r('app.media.normal') 
                      this.imageModel.imageSrc = this.src 
                      // this.imageModel.imageSrc = $r('app.media.wide') 
                      // todo: 
                      let sRatio = this.ratio 
                      if (sRatio > this.windowRatio) { 
                        // 宽度先到边界 
                        this.imageModel.initWidth = this.windowWidthVp 
                        this.imageModel.initHeight = this.imageModel.initWidth / sRatio 
                      } else { 
                        //   高度先到边界 
                        this.imageModel.initHeight = this.windowHeightVp 
                        this.imageModel.initWidth = this.imageModel.initHeight * sRatio 
                      } 
                      this.imageModel.initRatio = sRatio 
                      this.imageModel.pinchCenterX = event.pinchCenterX 
                      this.imageModel.pinchCenterY = event.pinchCenterY 
                      this.imageModel.handleScaleStart(event) 
                    }) 
                    .onActionUpdate((event: GestureEvent) => { 
                      this.imageModel.handleScaleUpdate(event) 
                    }) 
                    .onActionEnd((event: GestureEvent) => { 
                      this.imageModel.handleScaleEnd() 
                    }) 
                ) 
                .visibility(this.imageModel.isBothMode ? Visibility.Hidden : Visibility.Visible) 
 
              //   模拟正文内容 
              Text('模拟正文') 
                .width('100%') 
                .margin({ top: 30, bottom: 30 }) 
            } 
          }.layoutWeight(1).scrollBar(BarState.Off) 
 
          Divider().strokeWidth(0.5).color(0x14000000) 
          Row() { 
            Button('点赞') 
            Button('收藏').margin({ left: 20, right: 20 }) 
            Button('评论') 
          }.width('100%').height(50).justifyContent(FlexAlign.Center) 
        }.width('100%').height('100%').visibility(this.imageModel.isViewMode ? Visibility.Hidden : Visibility.Visible) 
 
        // 预览模式 
        Column() { 
          // 初始位置与笔记页面初始位置保持一致在进行缩放 
          Image(this.imageModel.imageSrc).objectFit(ImageFit.Contain)// 矩阵变换实现 
            .position({ x: this.imageInitialX, y: this.imageInitialY }) 
            .transform( 
              matrix4.identity() 
                .translate({ 
                  // px 单位 
                  // x: vp2px(this.imageModel.offsetX), 
                  // y: vp2px(this.imageModel.offsetY), 
                  // z: 1 
                }) 
                .scale({ 
                  // px 单位 
                  x: this.imageModel.curScale, 
                  y: this.imageModel.curScale, 
                  z: 1, 
                  centerX: this.imageModel.pinchCenterX, 
                  centerY: this.imageModel.pinchCenterY, 
                }) 
            ) 
          Text(` 
              offsetX: ${this.imageModel.offsetX}, 
              offsetY: ${this.imageModel.offsetY}, 
              curScale: ${this.imageModel.curScale}, 
              centerX: ${this.imageModel.centerX}, 
              centerY: ${this.imageModel.centerY}, 
              pinchCenterX: ${this.imageModel.pinchCenterX}, 
              pinchCenterY: ${this.imageModel.pinchCenterY}, 
              displayLeft: ${this.imageModel.displayLeft}, 
              displayRight: ${this.imageModel.displayRight}, 
              displayTop: ${this.imageModel.displayTop}, 
              displayBottom: ${this.imageModel.displayBottom}, 
                `) 
            .width('100%') 
            .fontColor(Color.Red) 
            .fontWeight(FontWeight.Bold) 
            .fontSize(14) 
            .position({ x: 0, y: 100 }) 
        } 
        .width('100%') 
        .height('100%') 
        .borderWidth(2) 
        .borderColor(Color.Red) 
        .justifyContent(FlexAlign.Center) 
        .alignItems(HorizontalAlign.Center) 
        .backgroundColor(this.imageModel.isBothMode ? Color.Transparent : Color.Black) 
        .visibility(this.imageModel.isViewMode || this.imageModel.isBothMode ? Visibility.Visible : Visibility.None) 
        // 捏合触发该手势事件 
        .gesture( 
          GestureGroup(GestureMode.Exclusive, 
            // 点击回到笔记模式 
            TapGesture() 
              .onAction((event: GestureEvent) => { 
                this.imageModel.reset() 
              }), 
            // 捏合缩放事件 
            PinchGesture() 
              .onActionStart((event) => { 
                // 放缩开始 
                this.imageModel.handleScaleStart(event) 
                this.imageModel.pinchCenterX = event.pinchCenterX 
                this.imageModel.pinchCenterY = event.pinchCenterY 
              }) 
              .onActionUpdate((event) => { 
                // console.log("hwn this.windowWidthVp = " + this.windowWidthVp) 
                // 放缩进行中 
                this.imageModel.handleScaleUpdate(event) 
              }) 
              .onActionEnd(() => { 
                // 放缩结束 
                this.imageModel.handleScaleEnd() 
              }) 
 
          ) 
        ) 
      }.width('100%').height('100%') 
    } 
    .width('100%') 
    .height('100%') 
    .hideTitleBar(true) 
    .backgroundColor(this.imageModel.isViewMode ? Color.Black : Color.White) 
  } 
}
分享
微博
QQ
微信
回复
2024-08-10 17:27:36
相关问题
HarmonyOS 能否提供登录界面样例demo
225浏览 • 1回复 待解决
HarmonyOS能否提供一个NFC识别的demo
403浏览 • 1回复 待解决
HarmonyOS 图像裁剪的demo
310浏览 • 1回复 待解决
HarmonyOS 如何实现下列功能,请提供demo
482浏览 • 1回复 待解决
能否提供一个关于SM3加密的demo
682浏览 • 1回复 待解决
能否提供图片预览的官方实现
275浏览 • 1回复 待解决
ArkTS卡片能否实现全透明效果
243浏览 • 1回复 待解决
HarmonyOS 希望能有实现topBar效果Demo
276浏览 • 1回复 待解决
HarmonyOS 能否提供脚本打包
69浏览 • 1回复 待解决
提供Webview demo有哪些?
208浏览 • 1回复 待解决