I struggle for a few days on this issue. I have a video editing timeline in a canva as you can see : [](The numbers are the frame's number of the video) I can zoom in and out in this timeline and scroll horizontally. I don't want to get outside my video length (I mean before the first frame and after the last one). This works well. The issue is when I scroll in my timeline I try to do it based on my cursor position as the origin. It works for zoom in, but not for zoom out if I change my cursor position between zoom in and zoom out You can find the function I used below : private coordinateXOnCanvas(event: MouseEvent): number { const rect = this.canvasRef.nativeElement.getBoundingClientRect(); return event.clientX - rect.left; } /** Zoom handling */ @HostListener('wheel', ['$event']) onWheel(event: WheelEvent) { event.preventDefault(); const zoomFactor = 1.1; const xOnCanvas = this.coordinateXOnCanvas(event); this.zoom = Math.min(Math.max(this.zoom * (event.deltaY < 0 ? zoomFactor : 1 / zoomFactor), 1), this.zoomMax); // Adjust offset to set cursor at the origin of zoom const notVisibleTimelineWidth = Math.abs(this.canvasWidth * this.zoom - this.canvasWidth); // Return in px the width of not visible timeline this.offsetX = Math.min(-notVisibleTimelineWidth * (xOnCanvas / this.canvasWidth), 0); //Set the offset to a percentage (depends on x) of not visible timeline console.log(this.offsetX); this.clampOffsetX(); this.drawTimeline(); } If you have any idea what should be the good equation, I would be gratefull ! I tried to change many times my function to determine my offset but I can't find one which fit the desired behavior Continue reading...