• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import Matrix4 from '@ohos.matrix4';
17import { PhotoItem } from './PhotoItem';
18import { BroadCastConstants } from '../model/common/BroadCastConstants';
19import { Log } from '../utils/Log';
20import { BroadCast } from '../utils/BroadCast';
21import Curves from '@ohos.curves';
22import { Constants } from '../model/common/Constants';
23import { Constants as BrowserConstants } from '../model/browser/photo/Constants';
24
25const TAG: string = 'common_PhotoSwiper';
26
27@Component
28export struct PhotoSwiper {
29  mTransition: string;
30  @Consume currentIndex: number;
31  @Link broadCast: BroadCast;
32  @State mDuration: number = 300;
33  onPhotoChanged: Function;
34  swiperController: SwiperController;
35  isInSelectedMode: boolean;
36  @Consume canSwipe: boolean;
37  swiperItemSpace: number = Constants.NUMBER_8;
38  verifyPhotoScaledFunc: (matrix: Matrix4.Matrix4Transit) => void
39  @Link isRunningAnimation: boolean;
40  isLeftSwiper: boolean = false;
41  @Consume isDeleting: boolean;
42  @State isOnSwiperAnimation: boolean = false;
43  private dataSource;
44  private geometryTransitionEnable: boolean = false;
45  private isFromFACard: boolean = false;
46  private SWIPE_CACHE_COUNT: number = 2;
47
48  aboutToAppear() {
49    this.broadCast.on(BroadCastConstants.ON_DATA_RELOADED, (addCount) => {
50      let totalCount = this.dataSource.totalCount();
51      if (addCount > Constants.NUMBER_0) {
52        this.dataSource.onDataReloaded();
53        if (this.currentIndex + addCount < totalCount) {
54          this.currentIndex += addCount;
55        }
56        Log.info(TAG, `ON_DATA_RELOADED: ${this.currentIndex}, ${addCount}`);
57        return;
58      }
59      Log.debug(TAG, 'animate to data reloaded start');
60      animateTo({
61        duration: 300, // 删除动画时长
62        curve: Curves.cubicBezier(0.0, 0.0, 0.2, 1.0), // 减速曲线参数
63        onFinish: () => {
64          let totalCount = this.dataSource.totalCount();
65          this.dataSource.onDataChanged(this.currentIndex);
66          // UPDATE NEXT TWO DATA FOR AVOID NOT LOADING DATA
67          if (this.currentIndex + 1 < totalCount) {
68            this.dataSource.onDataChanged(this.currentIndex + 1);
69          }
70          if (this.currentIndex + 2 < totalCount) {
71            this.dataSource.onDataChanged(this.currentIndex + 2);
72          }
73          this.dataSource.onDataReloaded();
74        } }, () => {
75        if (this.isDeleting) {
76          this.dataSource.deleteData(this.currentIndex);
77        }
78        if (this.currentIndex === this.dataSource.totalCount() || (this.isDeleting && this.isLeftSwiper && this.currentIndex > 0)) {
79          this.currentIndex--;
80        }
81        this.isDeleting = false;
82      })
83    });
84
85    this.broadCast.on(BroadCastConstants.CHANGE_SWIPER_DURATION, (value) => {
86      Log.debug(TAG, `change duration start ${value}`);
87      this.mDuration = value;
88    });
89  }
90
91  aboutToDisappear(): void {
92    this.swiperController = undefined;
93  }
94
95  build() {
96    Swiper(this.swiperController) {
97      LazyForEach(this.dataSource, (item, index?: number) => {
98        if (!!item) {
99          Column() {
100            PhotoItem({
101              item: item.data,
102              mPosition: item.pos,
103              thumbnail: item.thumbnail,
104              transitionTag: this.mTransition ? this.mTransition : 'default_id',
105              verifyPhotoScaled: this.verifyPhotoScaledFunc,
106              albumUri: this.dataSource.getAlbumUri(),
107              geometryTransitionEnable: this.geometryTransitionEnable,
108              broadCast: $broadCast,
109              isRunningAnimation: $isRunningAnimation,
110              isFromFACard: this.isFromFACard,
111              isInSelectedMode: this.isInSelectedMode,
112              isOnSwiperAnimation: $isOnSwiperAnimation,
113              dataSource: this.dataSource
114            })
115          }.zIndex(item.pos == this.currentIndex ? 2 : 1)
116        }
117      }, (item, index) => {
118        if (item == null || item == undefined) {
119          return JSON.stringify(item) + index;
120        }
121        return `${item.data.uri}_${item.data.size}_${item.data.orientation}_${index}`;
122      })
123    }
124    .cachedCount(this.SWIPE_CACHE_COUNT)
125    .duration(BrowserConstants.PHOTO_SWIPE_DURATION)
126    .itemSpace(this.swiperItemSpace)
127    .parallelGesture(PanGesture({
128      direction: PanDirection.Horizontal
129    })
130      .onActionStart((event: GestureEvent) => {
131        if (!this.canSwipe) {
132          this.isOnSwiperAnimation = true;
133        }
134      })
135    )
136    .index(this.currentIndex)
137    .indicator(false)
138    .loop(false)
139    .onChange((index: number) => {
140      if (this.currentIndex - index == 1) {
141        this.isLeftSwiper = true;
142      } else if (this.currentIndex - index == -1) {
143        this.isLeftSwiper = false;
144      }
145      if (this.mDuration != 0) {
146        this.onPhotoChanged(index);
147
148        if (!!this.verifyPhotoScaledFunc) {
149          this.verifyPhotoScaledFunc(undefined)
150        }
151      }
152    })
153    .disableSwipe(this.canSwipe)
154    .onAnimationStart((index: number) => {
155      this.isOnSwiperAnimation = true;
156    })
157    .onAnimationEnd(() => {
158      this.isOnSwiperAnimation = false;
159    })
160  }
161}