admin管理员组

文章数量:1125987

I've been struggling with implementing googlemaps-like zooming in html/css. I prepared minimal angular showcase project with my current buggy solution here. Problem I'm having is it only works how it's supposed to work when I scroll mousewheel few times while holding cursor at the same spot. When I change cursor position (and thus transformOrigin) rapidly and scroll for the first time, it offsets the position of zoomable div (red one) by some margin first. Could somebody please help me with explaining and possibly fixing this behaviour?

I've been struggling with implementing googlemaps-like zooming in html/css. I prepared minimal angular showcase project with my current buggy solution here. Problem I'm having is it only works how it's supposed to work when I scroll mousewheel few times while holding cursor at the same spot. When I change cursor position (and thus transformOrigin) rapidly and scroll for the first time, it offsets the position of zoomable div (red one) by some margin first. Could somebody please help me with explaining and possibly fixing this behaviour?

Share Improve this question asked 2 days ago peacem4kerpeacem4ker 713 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

The issue with your onZoom function is that it directly adjusts the transform style property but doesn't account for maintaining the zoom center properly over multiple zoom events.

Here is an updated onZoom function you could try out.

onZoom(event: WheelEvent): void {
  event.preventDefault();

  const zoomElement = this.zoomElement.nativeElement;
  const rect = zoomElement.getBoundingClientRect();

  // Calculate the mouse position relative to the zoom element
  const mouseX = (event.clientX - rect.left) / this.scale;
  const mouseY = (event.clientY - rect.top) / this.scale;

  // Adjust the scale factor
  const zoomFactor = 0.1;
  const delta = event.deltaY > 0 ? -zoomFactor : zoomFactor;
  const newScale = Math.min(Math.max(this.scale + delta, 0.5), 3);

  // Calculate the difference in scale to adjust transform origin correctly
  const scaleChange = newScale / this.scale;

  // Update the transform origin to maintain the zoom center
  const originX = mouseX - mouseX * scaleChange;
  const originY = mouseY - mouseY * scaleChange;

  // Update the scale and transform styles
  this.scale = newScale;
  zoomElement.style.transformOrigin = `0px 0px`;
  zoomElement.style.transform = `translate(${originX}px, ${originY}px) scale(${this.scale})`;
}

Stackblitz Demo

PS: It might be time for your application to be upgraded from Angular 8 to the latest version :)

For anyone interested, i managed to do what i wanted to do by compensating transformOrigin position change with translate transformation. If still doesn't work 100% i would like it to work but it's getting there. For once, translate animations are slacky when enabled and being compensated, so i might need to nest div into another with parent having scale animations and child having translate transform with animations disabled. Or something similar. Here is the snippet

本文标签: