问题
I'm searching for an image zoom solution for Angular 7, exactly like this
I've found this, but it's for AngularJs. Is there something good as the linked example?
回答1:
make a zoom it's only change the background with an image changing the background of a div according the move of the mouse, see, e.g. how create a image zoom in w3school
background-image:...
background-position:...
background-size
Imagine you has a component like:
<div class="img-zoom-container">
<img #img id="myimage" [src]="imagen" (load)="onLoad()">
<div #len [style.left] ="posX+'px'" [style.top] ="posY+'px'"
class="img-zoom-lens">
</div>
In Angular we use ViewChild to get reference to the "divs", and we can use Renderer2 to add the styles to the background of a div that we pass as input. So our app-component it's like
<app-zoom [img]="img" [divZoomed]="divZoomed" ></app-zoom>
<div #divZoomed class="img-zoom-result"></div>
We use the onLoad function to realize the calculates and put the background in "divZoomed"
onLoad()
{
this.render.setStyle(this.divZoomed,'background-image',"url('" + this.imagen+ "')");
this.render.setStyle(this.divZoomed,'background-size',(this.img.nativeElement.width * this.zoom) + "px " + (this.img.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');
const dim=(this.divZoomed as any).getBoundingClientRect()
this.cx=(dim.width-this.img.nativeElement.width*this.zoom)/(this.img.nativeElement.width - this.lens.nativeElement.offsetWidth);
this.cy=(dim.height-this.img.nativeElement.height*this.zoom)/(this.img.nativeElement.height -
this.lens.nativeElement.offsetHeight);
}
Using a HostListener, we get the mouse movement
@HostListener('mousemove',['$event'])
mouseMove(event:any)
{
const result=this.moveLens(event);
this.render.setStyle(this.divZoomed,'background-position',result)
}
The calculate of the position of the len and the final are a bit complex
moveLens(e:any)
{
let pos
let x
let y;
/*prevent any other actions that may occur when moving over the image:*/
e.preventDefault();
/*get the cursor's x and y positions:*/
pos = this.getCursorPos(e);
/*calculate the position of the lens:*/
x = pos.x - (this.lens.nativeElement.offsetWidth / 2);
y = pos.y - (this.lens.nativeElement.offsetHeight / 2);
/*prevent the lens from being positioned outside the image:*/
if (x > this.img.nativeElement.width - this.lens.nativeElement.offsetWidth) {x = this.img.nativeElement.width - this.lens.nativeElement.offsetWidth;}
if (x < 0) {x = 0;}
if (y > this.img.nativeElement.height - this.lens.nativeElement.offsetHeight) {y = this.img.nativeElement.height - this.lens.nativeElement.offsetHeight;}
if (y < 0) {y = 0;}
/*set the position of the lens:*/
this.posX = x;
this.posY = y;
/*display what the lens "sees":*/
let result = (x * this.cx) + "px "+(y * this.cy) + "px"
return result;
}
getCursorPos(e) {
let a, x = 0, y = 0;
e = e || window.event;
/*get the x and y positions of the image:*/
a = this.img.nativeElement.getBoundingClientRect();
/*calculate the cursor's x and y coordinates, relative to the image:*/
x = e.pageX - a.left;
y = e.pageY - a.top;
/*consider any page scrolling:*/
x = x - window.pageXOffset;
y = y - window.pageYOffset;
return {x : x, y : y};
}
The result in stackblitz
Update there minors changes in stackblitz to allow scale the image using two inputs imgWidth and imgHeigth. As the imagen is the same, this allow the preview image was minor than the real dimensions
回答2:
What about this ngx-img-zoom or this ngx-image-zoom
回答3:
I've been using CroppieJS multiple times and it works great with Angular, it's not just for zooming but also allows editing of images, hope it helps.
https://foliotek.github.io/Croppie/
来源:https://stackoverflow.com/questions/57396846/angular-7-image-zoom