Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Flickable calculate position depending on scale

Flickable calculate position depending on scale

Scheduled Pinned Locked Moved Solved QML and Qt Quick
2 Posts 1 Posters 1.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    maitai_vw
    wrote on last edited by
    #1

    Hello,
    I am relatively new to QML so probably I am missing something obvious.

    I am trying to "reproject" a flickable item (an image) to get its X, Y in original values in order to regenerate an image after a zoom or pan occurred. To make it short I need to know where is the topleft corner in the image source coordinates. It is very easy to do for a drag movement but I cannot find a solution when a pinch occurs.

    At the beginning the flickable item is centered on the center of the image, and I save the initial X and Y values:

        flick.contentWidth = img.sourceSize.width
        flick.contentHeight = img.sourceSize.height
        flick.contentX = (flick.contentWidth - rect.width) / 2
        flick.contentY = (flick.contentHeight - rect.height) / 2
        initialX = flick.contentX
        initialY = flick.contentY
        initialW = flick.contentWidth'
    

    Then when a drag occurs I get what I need with something like:

       backend.sendImageChange(flick.contentX - initialX, flick.contentY - initialY, 1.0)
    

    But I cannot figure a way to do it when a pinch occurs. I have no problem calculating the current scale which is initialW/contentWidth, but I cannot find a way to convert the new contentX and contentY back in original image coordinates. The pinchArea is:

        PinchArea {
            id: pi
            width: Math.max(flick.contentWidth, flick.width)
            height: Math.max(flick.contentHeight, flick.height)
    
            property real initialWidth
            property real initialHeight
            //![0]
            onPinchStarted: {
                initialWidth = flick.contentWidth
                initialHeight = flick.contentHeight
                console.log("pinch start", flick.contentX, flick.contentY, flick.contentWidth, flick.contentHeight, flick.scale)
            }
            onPinchUpdated: {
                // adjust content pos due to drag
                flick.contentX += pinch.previousCenter.x - pinch.center.x
                flick.contentY += pinch.previousCenter.y - pinch.center.y
                // resize content
                flick.resizeContent(initialWidth * pinch.scale, initialHeight * pinch.scale, pinch.center)
            }
    
            onPinchFinished: {
                // Move its content within bounds.
                flick.returnToBounds()
                console.log("pinch end", flick.contentX, flick.contentY, flick.contentWidth, flick.contentHeight, flick.scale)
                var scale = initialW / flick.contentWidth
                backend.sendImageChange(flick.contentX - initialX, flick.contentY - initialY, scale)
            }
    

    The flickable and the image behave as expected, but the calculated offset is wrong. I have tried to apply scale in various manners on contentX and contentY but couldn't find a working solution.

    Thanks in advance for any help or explanations
    Philippe.

    M 1 Reply Last reply
    0
    • M maitai_vw

      Hello,
      I am relatively new to QML so probably I am missing something obvious.

      I am trying to "reproject" a flickable item (an image) to get its X, Y in original values in order to regenerate an image after a zoom or pan occurred. To make it short I need to know where is the topleft corner in the image source coordinates. It is very easy to do for a drag movement but I cannot find a solution when a pinch occurs.

      At the beginning the flickable item is centered on the center of the image, and I save the initial X and Y values:

          flick.contentWidth = img.sourceSize.width
          flick.contentHeight = img.sourceSize.height
          flick.contentX = (flick.contentWidth - rect.width) / 2
          flick.contentY = (flick.contentHeight - rect.height) / 2
          initialX = flick.contentX
          initialY = flick.contentY
          initialW = flick.contentWidth'
      

      Then when a drag occurs I get what I need with something like:

         backend.sendImageChange(flick.contentX - initialX, flick.contentY - initialY, 1.0)
      

      But I cannot figure a way to do it when a pinch occurs. I have no problem calculating the current scale which is initialW/contentWidth, but I cannot find a way to convert the new contentX and contentY back in original image coordinates. The pinchArea is:

          PinchArea {
              id: pi
              width: Math.max(flick.contentWidth, flick.width)
              height: Math.max(flick.contentHeight, flick.height)
      
              property real initialWidth
              property real initialHeight
              //![0]
              onPinchStarted: {
                  initialWidth = flick.contentWidth
                  initialHeight = flick.contentHeight
                  console.log("pinch start", flick.contentX, flick.contentY, flick.contentWidth, flick.contentHeight, flick.scale)
              }
              onPinchUpdated: {
                  // adjust content pos due to drag
                  flick.contentX += pinch.previousCenter.x - pinch.center.x
                  flick.contentY += pinch.previousCenter.y - pinch.center.y
                  // resize content
                  flick.resizeContent(initialWidth * pinch.scale, initialHeight * pinch.scale, pinch.center)
              }
      
              onPinchFinished: {
                  // Move its content within bounds.
                  flick.returnToBounds()
                  console.log("pinch end", flick.contentX, flick.contentY, flick.contentWidth, flick.contentHeight, flick.scale)
                  var scale = initialW / flick.contentWidth
                  backend.sendImageChange(flick.contentX - initialX, flick.contentY - initialY, scale)
              }
      

      The flickable and the image behave as expected, but the calculated offset is wrong. I have tried to apply scale in various manners on contentX and contentY but couldn't find a working solution.

      Thanks in advance for any help or explanations
      Philippe.

      M Offline
      M Offline
      maitai_vw
      wrote on last edited by
      #2

      Finally got it: the offsets in original coordinates system can be calculated like that:

              var scale = flick.contentWidth / initialW
              var expectedX = ((flick.contentWidth - initialW) / 2.0) + initialX
              var expectedY = ((flick.contentHeight - initialH) / 2.0) + initialY
              var offsetX = (flick.contentX - expectedX) * scale
              var offsetY = (flick.contentY - expectedY) * scale
      
      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved