Skip to content

Commit

Permalink
feat: add product zoom functionality in fullscreen dialog (#1011, #1350)
Browse files Browse the repository at this point in the history
* use enhanced modal for product zoom images
* ICM 7.10.40.1 will provide product zoom demo data

Closes: #1011

Co-authored-by: Silke <s.grueber@intershop.de>
  • Loading branch information
2 people authored and shauke committed Apr 6, 2023
1 parent 1de7672 commit c839353
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 5 deletions.
28 changes: 25 additions & 3 deletions src/app/pages/product/product-images/product-images.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="col-lg-3 d-none d-lg-block">
<div class="product-img-thumbs">
<div
*ngFor="let imageView of getImageViewIDs$('S') | async; index as i"
*ngFor="let imageView of getImageViewIDs$('S') | async; let i = index"
class="product-thumb-set"
[ngClass]="{ active: isActiveSlide(i) }"
(click)="setActiveSlide(i)"
Expand All @@ -16,13 +16,35 @@
<div *ngIf="getImageViewIDs$('L') | async as largeImages" class="col-12 col-lg-9 product-detail-img clearfix">
<div class="product-image-container">
<swiper #carousel [navigation]="true">
<ng-container *ngFor="let imageView of largeImages">
<ng-container *ngFor="let imageView of largeImages; let i = index">
<ng-template swiperSlide>
<ish-product-image imageType="L" [imageView]="imageView"></ish-product-image>
<div (click)="openZoomModal(i)" (keydown.enter)="openZoomModal(i)">
<ish-product-image
[ngClass]="{ 'product-image-zoom': zoomImageIds$ | async }"
imageType="L"
[imageView]="imageView"
></ish-product-image>
</div>
</ng-template>
</ng-container>
</swiper>
<ish-product-label></ish-product-label>
</div>
</div>
</div>

<ish-modal-dialog
*ngIf="zoomImageIds$ | async as zoomImages"
#zoomDialog
[options]="{
scrollable: true,
modalDialogClass: 'modal-fullscreen'
}"
>
<ish-product-image
*ngFor="let imageView of zoomImages; let i = index"
[id]="getZoomImageAnchorId(i)"
imageType="ZOOM"
[imageView]="imageView"
></ish-product-image>
</ish-modal-dialog>
21 changes: 19 additions & 2 deletions src/app/pages/product/product-images/product-images.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { map, shareReplay } from 'rxjs/operators';
import SwiperCore, { Navigation } from 'swiper';
import { SwiperComponent } from 'swiper/angular';

import { ProductContextFacade } from 'ish-core/facades/product-context.facade';
import { ProductView } from 'ish-core/models/product-view/product-view.model';
import { ProductHelper } from 'ish-core/models/product/product.model';
import { ModalDialogComponent } from 'ish-shared/components/common/modal-dialog/modal-dialog.component';

SwiperCore.use([Navigation]);

/**
* The Product Images Component
*
* Displays carousel slides for all images of the product and a thumbnails list as carousel indicator.
* If zoom images are available and the user clicks on the image a zoom images dialog opens up.
* It uses the {@link ProductImageComponent} for the rendering of product images.
*
* @example
Expand All @@ -26,19 +28,22 @@ SwiperCore.use([Navigation]);
})
export class ProductImagesComponent implements OnInit {
@ViewChild('carousel') carousel: SwiperComponent;
@ViewChild('zoomDialog') zoomDialog: ModalDialogComponent<unknown>;

product$: Observable<ProductView>;
zoomImageIds$: Observable<string[]>;

constructor(private context: ProductContextFacade) {}

ngOnInit() {
this.product$ = this.context.select('product');
this.zoomImageIds$ = this.getImageViewIDs$('ZOOM').pipe(shareReplay(1));
}

getImageViewIDs$(imageType: string): Observable<string[]> {
return this.product$.pipe(
map(p => ProductHelper.getImageViewIDs(p, imageType)),
map(ids => (ids?.length ? ids : ['default']))
map(ids => (ids?.length ? ids : imageType === 'ZOOM' ? undefined : ['default']))
);
}

Expand All @@ -60,4 +65,16 @@ export class ProductImagesComponent implements OnInit {
isActiveSlide(slideIndex: number): boolean {
return this.carousel?.swiperRef?.activeIndex === slideIndex;
}

getZoomImageAnchorId(i: number) {
return `zoom-image-${i}`;
}

openZoomModal(i: number) {
if (this.zoomDialog) {
this.zoomDialog.show();
this.zoomDialog.scrollToAnchor(this.getZoomImageAnchorId(i));
}
return false;
}
}
1 change: 1 addition & 0 deletions src/styles/global/swiper.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
z-index: 10;
width: $carousel-control-icon-width;
height: 100%;
cursor: pointer;
background: no-repeat 50% / 100% 100%;
opacity: 0.5;

Expand Down
4 changes: 4 additions & 0 deletions src/styles/pages/productdetail/product-images.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
}
}

.product-image-zoom {
cursor: zoom-in;
}

.product-img-main {
float: left;
width: 95%;
Expand Down

0 comments on commit c839353

Please sign in to comment.