Flickable calculate position depending on scale
-
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. -
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.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