skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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


  2. 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 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search