GalleryImage.ets 5.26 KB
import display from '@ohos.display';

const TAG = 'GalleryImage'

@Component
export struct GalleryImage {
  private url: string = "";
  private index: number = 0;
  @State downLoadEnable: boolean = true;
  @Link isScaling: boolean
  @State showLoading: boolean = false;
  @State rotateAngle: number = 0;
  @State showError: boolean = false;
  @State scaleValue: number = 1;
  @State pinchValue: number = 1;
  @State pinchX: number | string = '50%';
  @State pinchY: number | string = '50%';
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.None, fingers: 1 })
  @State offsetX: number = 0
  @State offsetY: number = 0
  @State positionX: number = 0
  @State positionY: number = 0
  private imageWith: number = 0;
  @State sizeValue: number = 0;

  //alt app.media.picture_loading 设计稿尺寸
  @State imageWidth:string | number = 167

  aboutToAppear(): void {
    this.showLoading = true;
    this.downLoadEnable = false;
    console.info(TAG);
  }

  aboutToDisAppear(): void {
    console.info("");
  }

  aboutToReuse(): void {
    console.info("");
  }

  build() {
    Column() {
      Image(this.url)
        .width(this.imageWidth)
        .height("100%")
        .objectFit(ImageFit.Contain)//todo 加载失败时占位图没隐藏
        .alt($r("app.media.datail_imageLoading_w"))
        .interpolation(ImageInterpolation.High)
        .onComplete(msg => {
          if (msg) {
            this.imageWidth = '100%'
            console.info(TAG, "index:" + this.index + ", loadingStatus:" + msg.loadingStatus)
            // 图片数据加载成功
            if (msg.loadingStatus === 0) {
              this.showLoading = true;
              this.downLoadEnable = false;
            } else if (msg.loadingStatus === 1) {
              // 图片数据解码成功
              this.showLoading = false;
              this.downLoadEnable = true;
              this.imageWith = px2vp(display.getDefaultDisplaySync().width)
            }
          }
        })
        .onError(() => {
          console.info(TAG, "图片加载异常")
          this.showLoading = false;
          this.showError = true;
        })// 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大
        .scale({
          x: this.scaleValue,
          y: this.scaleValue,
          z: 1,
          centerX: this.pinchX,
          centerY: this.pinchY
        })// 以组件左上角为坐标原点进行移动
        .translate({ x: this.offsetX, y: this.offsetY, z: 0 })
        .gesture(
          GestureGroup(GestureMode.Parallel,
            // 两指或以上的捏合手势
            PinchGesture({ fingers: 2 })
              .onActionStart(() => {
                console.info(TAG, 'Pinch start');
              })// 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例
              .onActionUpdate((event: GestureEvent) => {
                const scaleValue = this.pinchValue * event.scale;
                if (scaleValue <= 3 && scaleValue >= 0.8) {
                  this.scaleValue = scaleValue;
                  this.pinchX = event.pinchCenterX;
                  this.pinchY = event.pinchCenterY;
                }
              })
              .onActionEnd(() => {
                this.pinchValue = this.scaleValue;
                console.info(TAG, 'Pinch end');
                if (this.pinchValue > 1) {
                  this.panOption.setDirection(PanDirection.Horizontal)
                  this.isScaling = true;
                } else {
                  this.panOption.setDirection(PanDirection.None)
                  this.isScaling = false;
                }
              }),
            // 绑定count为1的TapGesture
            TapGesture({ count: 1 })
              .onAction(() => {
              }),
            // 绑定count为2的TapGesture
            TapGesture({ count: 2 })
              .onAction(() => {
                console.info(TAG, '双击 start')
                animateTo({
                  duration: 400,
                }, () => {
                  this.scaleValue = 1;
                  this.pinchX = '50%';
                  this.pinchY = '50%';
                  this.pinchValue = this.scaleValue;
                  this.offsetX = 0;
                  this.offsetY = 0;
                  this.positionX = 0;
                  this.positionY = 0;
                  this.panOption.setDirection(PanDirection.None);
                  this.isScaling = false;
                })
              }),
            PanGesture(this.panOption)
              .onActionStart(() => {
                console.info(TAG, 'Pan start')
              })
              .onActionUpdate((event?: GestureEvent) => {
                if (event) {
                  if (this.scaleValue > 1) {
                    this.offsetX = this.positionX + event.offsetX
                    this.offsetY = this.positionY + event.offsetY
                    this.sizeValue = this.imageWith
                  }
                }
              })
              .onActionEnd(() => {
                this.positionX = this.offsetX
                this.positionY = this.offsetY
                console.info(TAG, 'Pan end')
              })
          ))
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}