当前并无相关组件可用于查看大图,具体实现方式可参考图库查看大图、左右切换浏览图片源码https://gitee.com/openharmony/applications_photos/tree/master,或者参考如下代码:1.Page页面:// xxx.ets import router from '@ohos.router' @Entry @Component struct SharedTransitionExample { @State active: boolean = false @State imageNames: Resource[] = [$r('app.media.image1'), $r('app.media.image2'), $r('app.media.image3')] @StorageLink('currentIndex') currentIndex: number = 0 build() { Row() { ForEach(this.imageNames, (res: Resource, index: number) => { Column() { Image(res) .width('100%') .height('100%') .objectFit(ImageFit.Contain) // 在组件上绑定缩放比例,可以通过修改缩放比例来实现组件的缩小或者放大 } .width(100) .height(100) .clip(true) .sharedTransition('sharedImage' + res.id, { duration: 200, curve: Curve.Linear, zIndex: this.currentIndex === index ? 10 : -10 }) .onClick(() => { this.currentIndex = index router.pushUrl({ url: 'pages/Index', params: { data: this.imageNames, } }) }) }) }.width('100%') .height('100%') } pageTransition() { PageTransitionEnter({ duration: 0, curve: Curve.Linear }) .onEnter((type?: RouteType, progress?: number) => { }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100%) PageTransitionExit({ duration: 0, curve: Curve.Ease }) .onExit((type?: RouteType, progress?: number) => { }) // 退场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0% -- 100%) } } //2.Index页面 import window from '@ohos.window'; import router from '@ohos.router'; interface Data { data: Resource[]; } enum Direction { None, Left, Right, } @Entry @Component struct Index { private swiperController: SwiperController = new SwiperController(); @State imageNames: Resource[] = [] @StorageLink('currentIndex') currentIndex: number = 0 @State screenWidth: number = 0; @State op: number = 0 aboutToAppear() { const data = (router.getParams() as Data) this.imageNames = data.data window.getLastWindow(getContext(this)).then(currentWindow => { let property = currentWindow.getWindowProperties(); this.screenWidth = property.windowRect.width; }) } build() { Stack({ alignContent: Alignment.Center }) { Swiper(this.swiperController) { ForEach(this.imageNames, (name: Resource, index: number) => { Column() { ImageComponent({ image: name, viewWidth: this.screenWidth, isCurrent: this.currentIndex === index, onNeedGoNext: (dire: Direction) => { if (dire === Direction.Right) { this.swiperController.showNext() } else if (dire === Direction.Left) { this.swiperController.showPrevious() } } }).zIndex(index == this.currentIndex ? 2 : 1) }.width('100%') .height('100%') .justifyContent(FlexAlign.Center) }) } .index(this.currentIndex) .indicator(false) .disableSwipe(true) .itemSpace(10) .onChange((index: number) => { this.currentIndex = index }) }.width('100%').height('100%') .backgroundColor(`rgba(0,0,0,${this.op})`) } pageTransition() { PageTransitionEnter({ duration: 200, curve: Curve.Linear }) .onEnter((type?: RouteType, progress?: number) => { if (progress) { this.op = progress } }) // 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0% -- 100 @Component struct ImageComponent { private image: Resource = $r('app.media.icon') private preGeometryScale: number = 1 @State geometryScale: number = 1 private preOffsetX: number = 0 private preOffsetY: number = 0 @State geometryOffsetX: number = 0 @State geometryOffsetY: number = 0 @State imageWidth: number = 0 @State imageHeight: number = 0 @Prop viewWidth: number = 0 @Prop isCurrent: boolean = false private dire: Direction = Direction.None private goNext: boolean = true private pinching: boolean = false private onNeedGoNext: (dire: Direction) => void = () => { } reset(): Promise<void> | undefined { this.preGeometryScale = 1 this.preOffsetX = 0 this.preOffsetY = 0 this.dire = Direction.None this.goNext = true if (this.geometryScale === 1) return return new Promise<void>(res => { animateTo({ duration: 200, onFinish: res }, () => { this.geometryScale = 1 this.geometryOffsetX = 0 this.geometryOffsetY = 0 }) }) } build() { Column() { Image(this.image) .onComplete((e) => { this.imageWidth = (e?.width || 0) this.imageHeight = (e?.height || 0) }) .objectFit(ImageFit.Cover) .width(this.imageWidth + 'px') .height(this.imageHeight + 'px') .scale({ x: this.geometryScale, y: this.geometryScale }) .offset({ x: this.geometryOffsetX, y: this.geometryOffsetY }) .focusable(true) .objectFit(ImageFit.Cover) .autoResize(false) .sharedTransition('sharedImage' + this.image.id, { duration: 200, curve: Curve.Linear, zIndex: this.isCurrent ? 10 : -10 }) } .clip(true) .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .hitTestBehavior(HitTestMode.Default) .parallelGesture( // 在组件上绑定二指触发的捏合手势 GestureGroup(GestureMode.Parallel, PinchGesture({ fingers: 2 }) .onActionStart((event: GestureEvent) => { this.pinching = true this.goNext = false })// 当捏合手势触发时,可以通过回调函数获取缩放比例,从而修改组件的缩放比例 .onActionUpdate((event: GestureEvent) => { const s = this.preGeometryScale * event.scale; this.geometryScale = Math.max(0.6, Math.min(2, s)) }) .onActionEnd(async () => { this.preGeometryScale = this.geometryScale if (this.preGeometryScale < 1) { await this.reset() } this.pinching = false }), PanGesture() .onActionStart((event?: GestureEvent) => { }) .onActionUpdate((event?: GestureEvent) => { let offsetX = this.preOffsetX + (event?.offsetX || 0) let offsetY = this.preOffsetY + (event?.offsetY || 0) if (((this.imageWidth * this.geometryScale - this.viewWidth) / 2 - Math.abs(vp2px(offsetX))) <= 0) { if (!this.pinching) { this.dire = offsetX < 0 ? Direction.Right : Direction.Left } return; } this.goNext = false this.geometryOffsetX = offsetX this.geometryOffsetY = offsetY }) .onActionEnd((event?: GestureEvent) => { if ((this.dire !== Direction.None)) { if (this.goNext) { this.onNeedGoNext(this.dire) this.reset() } this.goNext = true } this.preOffsetX = this.geometryOffsetX this.preOffsetY = this.geometryOffsetY }), ) ) } }
当前并无相关组件可用于查看大图,具体实现方式可参考图库查看大图、左右切换浏览图片源码https://gitee.com/openharmony/applications_photos/tree/master,或者参考如下代码:
1.Page页面: