Qt 放大图像,同时保持图像居中

Qt 放大图像,同时保持图像居中,qt,math,qml,transformation,qtquick2,Qt,Math,Qml,Transformation,Qtquick2,在下面的应用程序中,可以单击场景中的任意位置,将“视图”置于该点的中心 import QtQuick 2.7 import QtQuick.Controls 2.2 ApplicationWindow { width: 640 height: 480 visible: true property real zoom: 1 property point offset property point scenePosToCentreOn I

在下面的应用程序中,可以单击场景中的任意位置,将“视图”置于该点的中心

import QtQuick 2.7
import QtQuick.Controls 2.2

ApplicationWindow {
    width: 640
    height: 480
    visible: true

    property real zoom: 1
    property point offset
    property point scenePosToCentreOn

    Item {
        id: sceneView
        anchors.fill: parent

        MouseArea {
            anchors.fill: parent
            onClicked: {
                scenePosToCentreOn = scene.mapFromItem(sceneView, mouse.x, mouse.y)
                offset = Qt.point(scenePosToCentreOn.x - width / 2,
                                  scenePosToCentreOn.y - height / 2);
            }
            onWheel: {
                var zoomFactor = Math.pow(1.4, wheel.angleDelta.y / 120.0);
                var newZoom = Math.min(8.0, Math.max(0.25, zoom * zoomFactor));
                zoom = newZoom;
            }
        }

        Item {
            id: scene
            implicitWidth: backgroundImage.implicitWidth
            implicitHeight: backgroundImage.implicitHeight

            transform: [
                Translate {
                    x: -offset.x
                    y: -offset.y
                },
                Scale {
                    xScale: zoom
                    yScale: zoom
                }
            ]

            Image {
                id: backgroundImage
                source: "http://cdn.akamai.steamstatic.com/steam/apps/393010/ss_29cf93db42617dd08ceb0a0bf0a4b62ad12a1cfc.1920x1080.jpg?t=1459456906"
            }

            Rectangle {
                x: scenePosToCentreOn.x - width / 2
                y: scenePosToCentreOn.y - height / 2
                width: 8
                height: width
                radius: width / 2
                color: "#fff"
            }

            Rectangle {
                anchors.fill: parent
                color: "transparent"
                border.color: "darkorange"
                border.width: 4

                Label {
                    text: "Scene"
                }
            }
        }

        Label {
            text: zoom.toFixed(2)
            font.pixelSize: Qt.application.font.pixelSize * 2
            color: "salmon"
            anchors.right: parent.right
            anchors.bottom: parent.bottom
        }
    }
}

我希望能够放大和缩小选定的点(
scenePosToCentreOn
)。当
zoom
1
时,它当前工作,但对于任何其他
zoom
值,它的原点似乎位于屏幕左上角。我怀疑我在变换列表中遗漏了什么,但我无法找出它。

由于计算居中位置和应用比例的方式,您需要进行补偿

    Translate {
      x: -offset.x + (((1 / zoom) - 1) * (sceneView.width * .5))
      y: -offset.y + (((1 / zoom) - 1) * (sceneView.height * .5))
    },

由于计算中心位置和应用刻度的方式,您需要进行补偿

    Translate {
      x: -offset.x + (((1 / zoom) - 1) * (sceneView.width * .5))
      y: -offset.y + (((1 / zoom) - 1) * (sceneView.height * .5))
    },

标签是相关的,请不要更改我的英国英语。:)我会看看这个答案,看看它是否有帮助。为什么相机是相关的?视图是一个镜头到现场。最初的用例是一个游戏,所以我想吸引有这方面经验的人。概念上是的,但这个元素在这种情况下不合适,最好使用更通用的标记,如
qt
,这样你会吸引更多可以帮助你的人。好吧,公平点。关于帮助的问题,我不知道你投票的答案是如何结束我的问题的,因为它是解决我问题的答案的副本。也许您愿意发布一个答案,其中的代码与我的代码片段相适应?:)标签是相关的,请不要更改我的英国英语。:)我会看看这个答案,看看它是否有帮助。为什么相机是相关的?视图是一个镜头到现场。最初的用例是一个游戏,所以我想吸引有这方面经验的人。概念上是的,但这个元素在这种情况下不合适,最好使用更通用的标记,如
qt
,这样你会吸引更多可以帮助你的人。好吧,公平点。关于帮助的问题,我不知道你投票的答案是如何结束我的问题的,因为它是解决我问题的答案的副本。也许您愿意发布一个答案,其中的代码与我的代码片段相适应?:)谢谢((z/zoom)-1)部分的作用是什么?由于您将变换和缩放应用于同一项目,因此,如果小于1,缩放将减小偏移量,如果大于1,缩放将放大偏移量。比例为0.5时,偏移量仅为必须偏移量的50%,比例为2时偏移量为200%。所讨论的部分只是计算缩放比率
1/zoom
,然后减去1将其“规格化”为零,因此缩放1的补偿为0。因此,最终得到的值介于-1和x之间,即由于缩放,中心点偏离场景中心的像素数。此外,我可能会选择“相对”中心点,而不是绝对,然后根据相对大小和窗口大小计算绝对值,因此,当窗口大小改变时,绝对中心点也会改变,所以当窗口大小改变时,你也可以保持事物居中,这是你目前没有的。啊,谢谢!这是有道理的。至于相对中心点的问题,你想把它编辑成你的答案吗?听起来不错,但我不知道怎么做。谢谢!((z/zoom)-1)部分的作用是什么?由于您将变换和缩放应用于同一项目,因此,如果小于1,缩放将减小偏移量,如果大于1,缩放将放大偏移量。比例为0.5时,偏移量仅为必须偏移量的50%,比例为2时偏移量为200%。所讨论的部分只是计算缩放比率
1/zoom
,然后减去1将其“规格化”为零,因此缩放1的补偿为0。因此,最终得到的值介于-1和x之间,即由于缩放,中心点偏离场景中心的像素数。此外,我可能会选择“相对”中心点,而不是绝对,然后根据相对大小和窗口大小计算绝对值,因此,当窗口大小改变时,绝对中心点也会改变,所以当窗口大小改变时,你也可以保持事物居中,这是你目前没有的。啊,谢谢!这是有道理的。至于相对中心点的问题,你想把它编辑成你的答案吗?听起来不错,但我不知道怎么做。