/*
* Copyright (c) 2023 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 display from '@ohos.display';
import router from '@ohos.router';
import Constants from '../common/Constants';
import MyDataSource from '../bean/MyDataSource';
@Entry
@Component
struct DetailPage {
scroller: Scroller = new Scroller();
photoArr: MyDataSource = AppStorage.get('photoArr') as MyDataSource;
preOffsetX: number = 0;
preOffsetY: number = 0;
currentScale: number = 1;
@State deviceWidth: number = Constants.DEFAULT_WIDTH;
@State smallImgWidth: number = (Constants.DEFAULT_WIDTH - Constants.LIST_ITEM_SPACE * (Constants.SHOW_COUNT - 1)) /
Constants.SHOW_COUNT;
@State imageWidth: number = this.deviceWidth + this.smallImgWidth;
@StorageLink('selectedIndex') selectedIndex: number = 0;
@State isScaling: boolean = true;
@State imgScale: number = 1;
@State imgOffSetX: number = 0;
@State imgOffSetY: number = 0;
@State bgOpacity: number = 0;
aboutToAppear() {
console.log('selectedIndex:' + this.selectedIndex);
let width = Constants.DEFAULT_WIDTH;
this.deviceWidth = width;
this.smallImgWidth = (width - Constants.LIST_ITEM_SPACE * (Constants.SHOW_COUNT - 1)) / Constants.SHOW_COUNT;
this.imageWidth = this.deviceWidth + this.smallImgWidth;
}
resetImg(): void {
this.imgScale = 1;
this.currentScale = 1;
this.preOffsetX = 0;
this.preOffsetY = 0;
}
handlePanEnd(): void {
let initOffsetX = (this.imgScale - 1) * this.imageWidth + this.smallImgWidth;
if (Math.abs(this.imgOffSetX) > initOffsetX) {
if (this.imgOffSetX > initOffsetX && this.selectedIndex > 0) {
this.selectedIndex -= 1;
} else if (this.imgOffSetX < -initOffsetX && this.selectedIndex < (this.photoArr.totalCount() - 1)) {
this.selectedIndex += 1;
}
this.isScaling = false;
this.resetImg();
this.scroller.scrollTo({ xOffset: this.selectedIndex * this.imageWidth, yOffset: 0 });
}
}
checkIsVideo(message: string): boolean {
if (message.includes('mp4') || message.includes('mov') || message.includes('MP4') || message.includes('MOV')) {
return true;
} else {
return false;
}
}
build() {
Column() {
Stack() {
Image($r('app.media.back'))
.width(30)
.position({ x: 10, y: 0 })
Text('')
.fontSize(Constants.PAGE_TITLE_SIZE)
.width(Constants.FULL_PERCENT)
.textAlign(TextAlign.Center)
}
.backgroundColor('#f7f7f7')
.padding(7)
.onClick(() => {
router.back();
})
Stack() {
List({ scroller: this.scroller, initialIndex: this.selectedIndex }) {
LazyForEach(this.photoArr, (img: Resource) => {
ListItem() {
Image(img)
.objectFit(ImageFit.Contain)
.onClick(() => router.back())
}
.gesture(GestureGroup(GestureMode.Exclusive,
PinchGesture({ fingers: Constants.DOUBLE_NUMBER })
.onActionStart(() => {
this.resetImg();
this.isScaling = true;
this.imgOffSetX = 0;
this.imgOffSetY = 0;
})
.onActionUpdate((event?: GestureEvent) => {
if (event) {
this.imgScale = this.currentScale * event.scale;
}
})
.onActionEnd(() => {
if (this.imgScale < 1) {
this.resetImg();
this.imgOffSetX = 0;
this.imgOffSetY = 0;
} else {
this.currentScale = this.imgScale;
}
}), PanGesture()
.onActionStart(() => {
this.resetImg();
this.isScaling = true;
})
.onActionUpdate((event?: GestureEvent) => {
if (event) {
this.imgOffSetX = this.preOffsetX + event.offsetX;
this.imgOffSetY = this.preOffsetY + event.offsetY;
}
})
))
.padding({
left: this.smallImgWidth / Constants.DOUBLE_NUMBER,
right: this.smallImgWidth / Constants.DOUBLE_NUMBER
})
.width(this.imageWidth)
}, (item: Resource) => JSON.stringify(item))
}
.cachedCount(15)
.onScrollStop(() => {
let currentIndex = Math.round(((this.scroller.currentOffset().xOffset as number) +
(this.imageWidth / Constants.DOUBLE_NUMBER)) / this.imageWidth);
this.selectedIndex = currentIndex;
this.scroller.scrollTo({ xOffset: currentIndex * this.imageWidth, yOffset: 0 });
})
.width(Constants.FULL_PERCENT)
.height(Constants.FULL_PERCENT)
.listDirection(Axis.Horizontal)
.visibility(this.isScaling ? Visibility.Hidden : Visibility.Visible)
Row() {
if (this.checkIsVideo(this.photoArr.getData(this.selectedIndex) as string)) {
Video({ src: this.photoArr.getData(this.selectedIndex) as string })
.controls(true)
.autoPlay(true)
.height('100%')
.width('100%')
.objectFit(ImageFit.Contain)
.position({ x: this.imgOffSetX, y: this.imgOffSetY })
} else {
Image(this.photoArr.getData(this.selectedIndex) as string)
.position({ x: this.imgOffSetX, y: this.imgOffSetY })
.scale({ x: this.imgScale, y: this.imgScale })
.objectFit(ImageFit.Contain)
}
}
.gesture(GestureGroup(GestureMode.Exclusive,
PinchGesture({ fingers: Constants.DOUBLE_NUMBER })
.onActionUpdate((event?: GestureEvent) => {
if (event) {
this.imgScale = this.currentScale * event.scale;
}
})
.onActionEnd(() => {
this.resetImg();
this.imgOffSetX = 0;
this.imgOffSetY = 0;
}),
PanGesture({ direction: PanDirection.None })
.onActionStart(() => {
this.preOffsetX = this.imgOffSetX;
this.preOffsetY = this.imgOffSetY;
})
.onActionUpdate((event?: GestureEvent) => {
if (event) {
this.imgOffSetX = this.preOffsetX + event.offsetX;
this.imgOffSetY = this.preOffsetY + event.offsetY;
}
})
.onActionEnd(() => this.handlePanEnd())
))
.padding({
left: this.smallImgWidth / Constants.DOUBLE_NUMBER,
right: this.smallImgWidth / Constants.DOUBLE_NUMBER
})
.width(Constants.FULL_PERCENT)
.height(Constants.FULL_PERCENT)
.visibility(this.isScaling ? Visibility.Visible : Visibility.Hidden)
}
.width(this.imageWidth)
.height(Constants.FULL_PERCENT)
}
}
}