This is my product image viewer component.html. In this component the template reference variable #divZoomed is used to display the zoom.
<div style="position: sticky; top: 56px;">
<div class="row no-gutters">
<div class="col-md-2">
<div class="flex flex-column justify-content-center">
<div class="image-border" *ngFor="let image of images">
<div
[style.backgroundImage]="'url(' + image + ')'"
style="
padding: 5px;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: 50%;
background-size: contain;
height: 64px;
"
(click)="getCurrentImage(image)"
></div>
</div>
</div>
</div>
<div class="col-md-10">
<div style="border: 1px solid #f0f0f0;">
<app-zoom [img]="currentImage" [zoom]="2" [lenSize]="50" [divZoomed]="divZoomed"></app-zoom>
<div
#divZoomed
class="img-zoom-result"
style="left: 405.341px; width: 736.673px; height: 425.105px;"
></div>
<div class="mt-3"></div>
<button class="add-to-card">
<i class="fas fa-shopping-cart"></i>
Add To Basket
</button>
</div>
</div>
</div>
</div>
This is my product image viewer component.css
.image-border {
border-right: none !important;
border: 1px solid #f0f0f0;
border-bottom: none;
cursor: pointer;
}
.add-to-card {
padding: 18px 8px;
border-radius: 2px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
width: 60%;
border: none;
float: left;
background: #ff9f00;
color: #fff;
text-transform: uppercase;
font-size: 16px;
font-weight: 500;
transition: box-shadow 0.2s ease;
vertical-align: super;
cursor: pointer;
}
.img-zoom-result {
border: 1px solid #d4d4d4;
left: 405.341px;
width: 736.673px;
height: 234.009px;
z-index: 1000000000;
position: absolute;
top: 0;
overflow: hidden;
background: #fff;
border-radius: 4px;
border: 1px solid #e0e0e0;
box-shadow: 0 4px 20px 2px rgba(0, 0, 0, 0.2);
pointer-events: none;
opacity: 0;
}
This is my product image viewer component.ts
import { Component } from '@angular/core'
@Component({
selector: 'app-product-image-viewer',
templateUrl: './product-image-viewer.component.html',
styleUrls: ['./product-image-viewer.component.scss'],
})
export class ProductImageViewerComponent {
images = [
'https://www.bigbasket.com/media/uploads/p/l/20000979_10-fresho-palak.jpg',
'https://www.bigbasket.com/media/uploads/p/l/10000148_28-fresho-onion.jpg',
'https://www.bigbasket.com/media/uploads/p/l/10000293_12-fresho-amla.jpg',
]
currentImage: string = this.images[0]
getCurrentImage(imageUrl: string) {
this.currentImage = imageUrl
}
}
This is my zoom component.html
<div class="img-zoom-container">
<img
#image
[style.width]="yet && imgWidth ? imgWidth + 'px' : null"
[style.heigth]="yet && imgHeigth ? imgHeigth + 'px' : null"
id="myimage"
[src]="imagen"
(load)="onLoad()"
/>
<div
#lens
[style.width]="lenSize + 'px'"
[style.height]="lenSize + 'px'"
[style.left]="posX + 'px'"
[style.top]="posY + 'px'"
class="img-zoom-lens"
></div>
</div>
This is my zoom component.css
.img-zoom-container {
position: relative;
}
.img-zoom-lens {
position: absolute;
border: 1px solid #d4d4d4;
}
This is my zoom component.ts. In this component renderer is used to set the style. I used viewchild for #lens and #image
import {
Component,
OnInit,
Input,
ElementRef,
ViewChild,
HostListener,
Renderer2,
} from '@angular/core'
@Component({
selector: 'app-zoom',
templateUrl: './zoom.component.html',
styleUrls: ['./zoom.component.scss'],
})
export class ZoomComponent implements OnInit {
ngOnInit() {}
imageTag: Element
@Input('img') imagen: string
@Input() zoom = 2
@Input() lenSize = 40
@Input() imgWidth
@Input() imgHeigth
@Input() divZoomed: ElementRef
//@Input() imageResult: ElementRef
result
posX: number = 0
posY: number = 0
cx: number = 1
cy: number = 1
yet: boolean = false
factorX: number
factorY: number
@ViewChild('image', { static: false, read: ElementRef }) image
@ViewChild('lens', { static: false, read: ElementRef }) lens
@HostListener('mousemove', ['$event'])
mouseMove(event: any) {
const result = this.moveLens(event)
this.render.setStyle(this.divZoomed, 'background-position', result)
this.render.setStyle(this.divZoomed, 'opacity', 1)
}
@HostListener('mouseleave', ['$event'])
mouseLeave(event: any) {
this.render.setStyle(this.divZoomed, 'opacity', 0)
}
constructor(private render: Renderer2) {}
onLoad() {
this.render.setStyle(this.divZoomed, 'background-image', "url('" + this.imagen + "')")
this.render.setStyle(
this.divZoomed,
'background-size',
this.image.nativeElement.width * this.zoom +
'px ' +
this.image.nativeElement.height * this.zoom +
'px'
)
this.render.setStyle(this.divZoomed, 'background-repeat', 'no-repeat')
this.render.setStyle(this.divZoomed, 'transition', 'background-position .2s ease-out')
this.factorX = this.image.nativeElement.width
this.factorY = this.image.nativeElement.height
this.yet = true
setTimeout(() => {
this.factorX =
this.imgWidth || this.imgHeigth ? this.factorX / this.image.nativeElement.width : 1
this.factorY =
this.imgWidth || this.imgHeigth ? this.factorY / this.image.nativeElement.height : 1
const dim = (this.divZoomed as any).getBoundingClientRect()
this.cx =
(dim.width - this.image.nativeElement.width * this.zoom * this.factorX) /
(this.image.nativeElement.width - this.lens.nativeElement.offsetWidth)
this.cy =
(dim.height - this.image.nativeElement.height * this.zoom * this.factorY) /
(this.image.nativeElement.height - this.lens.nativeElement.offsetHeight)
})
}
moveLens(e: any) {
let pos
let x
let y
e.preventDefault()
pos = this.getCursorPos(e)
x = pos.x - this.lens.nativeElement.offsetWidth / 2
y = pos.y - this.lens.nativeElement.offsetHeight / 2
if (x > this.image.nativeElement.width - this.lens.nativeElement.offsetWidth) {
x = this.image.nativeElement.width - this.lens.nativeElement.offsetWidth
}
if (x < 0) {
x = 0
}
if (y > this.image.nativeElement.height - this.lens.nativeElement.offsetHeight) {
y = this.image.nativeElement.height - this.lens.nativeElement.offsetHeight
}
if (y < 0) {
y = 0
}
this.posX = x
this.posY = y
let result = x * this.cx + 'px ' + y * this.cy + 'px'
return result
}
getCursorPos(e: any) {
let a
let x = 0
let y = 0
e = e || window.event
a = this.image.nativeElement.getBoundingClientRect()
x = e.pageX - a.left
y = e.pageY - a.top
x = x - window.pageXOffset
y = y - window.pageYOffset
return { x: x, y: y }
}
}
This works fine.I am not able to bring the background image front. I used zindex, it is not working.Is there any other method to done this?
I created stackblitz for this issue.
https://stackblitz.com/edit/angular-ivy-tuw2xg?file=src%2Fapp%2Fapp.component.html
You cannot set z-index
direcly on your zoom component, since it's at a deeper level in the DOM than the text. You need to set the z-index higher up in the DOM.
I just set it in the col-md-5
container
<div class="col-md-5" style=";z-index:10">
<app-a ></app-a>
</div>
<div class="col-md-7">
Your product details