title: Creating a timeline view in swiftui messes up alignment
body: <p>I need to create an interactive &quot;timeline&quot; view, that can be panned and zoomed, in SwiftUI (2.0, iOS 14). Think of a media player's progress view, but interactive. The audio needs to be some shape (I just chose RoundedRectangle as example below) and the &quot;current&quot; time needs to be denoted as a vertical (yellow) line in middle of screen.</p>
  <p><a href="https://i.stack.imgur.com/NqAYR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/NqAYR.png" alt="At zoom level 1" /></a></p>
  <p>As I need to be able to both set and get the offset, I am unable to use a horizontal ScrollView. Instead, I just thought of changing the frame size of the shape based on zoom level. The &quot;current&quot; time line is then painted as overlay. At zoom levels up to 0.5, everything works fine.</p>
  <p>However, when I zoom in (i.e. make the value of zoomLevel smaller than 0.45), the alignment just goes haywire. I have tried ZStack and a few other combinations without luck. I believe the issue is that the shape size is causing the overlay's location to be miscalculated, but even with ZStack alignment set to [.leading, .center] I am unable to get the yellow line and the shape aligned.</p>
  <p><a href="https://i.stack.imgur.com/7lGei.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/7lGei.png" alt="At zoom level 0.3" /></a></p>
  <p>Here is the code. What can I do to ensure that as I resize the shape, the overlay yellow line as well as the offset for the shape are calculated correctly so that they remain in center of screen?</p>
  <pre><code>    let zoomLevel:CGFloat = 1  // This is the value being modified
      var body: some View {
          GeometryReader { geometry in
                  RoundedRectangle(cornerRadius: 5)
                      .offset(x: getOffset(with: geometry.size.width))
                      .frame(width: getWidth(with: geometry.size.width), height: 150)
                      .overlay(Rectangle()
                              .frame(width: 2, height: geometry.size.height/5)
                              .foregroundColor(.yellow)
                      )
                      .frame(maxWidth: .infinity)
                  }
          }
      }
  </code></pre>
  <p>and the functions are:</p>
  <pre><code>    
      private func getOffset(with width: CGFloat)-&gt;CGFloat {
          let currentWidth = getWidth(with: width)
          let offset = currentWidth/2 + 0  // 0 would be replaced with pan offset later
  
          if offset &gt; currentWidth/2 {
              return currentWidth/2
          } else if offset &lt; -currentWidth/2 {
              return -currentWidth/2
          }
          return offset
      }
      
      private func getWidth(with width: CGFloat)-&gt;CGFloat {
          return 0.45*width/zoomLevel
      }
      
      
  </code></pre>