c77fb700创建于 2025年1月16日历史提交
/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { CommonConstants as Const } from '@ohos/utils';
import ZonesItem from '../viewmodel/ZonesItem';
import { ImageView } from './ImageViewComponent';

@Component
export default struct ImageAnimation {
  @StorageLink('imageId') imageId: number = Const.HALF_COUNT;
  @Consume('introductionData') introductionData: ZonesItem;
  dialogController: CustomDialogController = new CustomDialogController({
    builder: ImageView({ currentImageId: this.imageId }),
    customStyle: true,
    alignment: DialogAlignment.Bottom,
  });

  aboutToAppear() {
    if (AppStorage.get<string>('isContinuation') === 'true' && AppStorage.get<boolean>('imageModalOpen')) {
      this.dialogController.open();
    }
  }

  /**
   * Get the image offset coefficients.
   *
   * @param index
   * @returns offset coefficients
   */
  getImgCoefficients(index: number) {
    let coefficient = this.imageId - index;
    let tempCoefficient = Math.abs(coefficient);
    if (tempCoefficient <= Const.HALF_COUNT) {
      return coefficient;
    }
    let dataLength = this.introductionData.imageList.length;
    let tempOffset = dataLength - tempCoefficient;
    if (tempOffset <= Const.HALF_COUNT) {
      if (coefficient > 0) {
        return -tempOffset;
      }
      return tempOffset;
    }
    return 0;
  }

  /**
   * Get the image offset.
   *
   * @param index
   * @returns offset
   */
  getOffSetX(index: number) {
    let offsetIndex = this.getImgCoefficients(index);
    let tempOffset = Math.abs(offsetIndex);
    let offsetX = 0;
    if (tempOffset === 1) {
      offsetX = -Const.IMAGE_X_OFFSET_MAX * offsetIndex;
    } else if (tempOffset === Const.HALF_COUNT) {
      offsetX = -Const.IMAGE_x_OFFSET_MIN * offsetIndex;
    }
    return offsetX;
  }

  startAnimation(isLeft: boolean) {
    animateTo({
      duration: Const.IMAGE_ANIMATION_DURATION,
    }, () => {
      let dataLength = this.introductionData.imageList.length;
      let tempIndex = isLeft ? this.imageId + 1 : this.imageId - 1 + dataLength;
      this.imageId = tempIndex % dataLength;
    })
  }

  build() {
    Stack() {
      ForEach(this.introductionData.imageList, (item: ResourceStr, index: number) => {
        Row() {
          Image(item)
            .objectFit(ImageFit.ScaleDown)
            .borderRadius($r('app.float.small_image_border_radius'))
            .opacity(Const.OPACITY_MAX - Const.IMAGE_OPACITY_REDUCE
              * Math.min(Const.HALF_COUNT, Math.abs(this.getImgCoefficients(index))))
        }
        .aspectRatio(Const.IMAGE_ASPECT_RATIO)
        .borderRadius($r('app.float.small_image_border_radius'))
        .offset({ x: this.getOffSetX(index), y: 0 })
        .blur(Const.IMAGE_BLUR_REDUCE * Math.abs(this.getImgCoefficients(index)))
        .zIndex(index != this.imageId && this.getImgCoefficients(index) == 0 ?
          0 : Const.HALF_COUNT - Math.abs(this.getImgCoefficients(index)))
        .height(index != this.imageId && this.getImgCoefficients(index) === 0 ?
        Const.IMAGE_HEIGHT_MIN : `${Const.FULL_PERCENT_NUMBER -
            Const.IMAGE_WIDTH_OFFSET * Math.abs(this.getImgCoefficients(index))}%`)
        .onClick(() => {
          this.dialogController.open();
        })
      }, (item: ResourceStr) => JSON.stringify(item))
    }
    .width(Const.FULL_SIZE)
    .height(Const.FULL_SIZE)
    .alignContent(Alignment.Center)
    .gesture(
      PanGesture({ direction: PanDirection.Horizontal })
        .onActionStart((event: GestureEvent) => {
          this.startAnimation(event.offsetX < 0);
        })
    )
  }
}