【问题标题】:Zooming in on an image whilst keeping it centered在保持居中的同时放大图像
【发布时间】:2018-07-04 01:11:40
【问题描述】:

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

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)。它目前在zoom1 时有效,但对于任何其他zoom 值,它似乎起源于屏幕的左上角。我怀疑我在转换列表中遗漏了一些东西,但我想不通。

【问题讨论】:

  • 标签是相关的,请不要更改我的英式英语。 :) 我会看看那个答案,看看它是否有帮助。
  • 为什么相机是相关的?
  • 视图是场景中的相机。最初的用例是一个游戏,所以我想吸引有这方面经验的人。
  • 概念上是的,但是这个元素在这种情况下是不合适的,最好使用像qt这样更通用的标签,这样你会吸引更多可以帮助你的人。
  • 好的,公平点。关于帮助的问题,我看不出你投票结束我的问题的答案是如何解决我的问题的。也许您愿意使用适合我的 sn-p 的代码发布答案? :)

标签: qt math qml transformation qtquick2


【解决方案1】:

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

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

【讨论】:

  • 谢谢! ((z / zoom) - 1) 部分有什么作用?
  • 由于您将转换和缩放应用于同一个项目,如果小于 1,您的缩放会减小偏移量,如果高于 1,则会夸大偏移量。在比例 0.5 时,您的偏移量仅达到 50%它必须这样,在第 2 级时,它会达到 200%。有问题的部分只是计算缩放比率1 / zoom,然后减去 1 以将其“归一化”为零,因此您对 1 的缩放有 0 补偿。所以您最终得到一个介于 -1 和 x 之间的值,即由于缩放,您的中心点偏离场景中心多少像素。
  • 另外,我可能会选择一个“相对”中心点而不是绝对,然后从相对和窗口大小计算绝对值,这样当窗口大小改变时,绝对中心点就会改变,所以随着窗口大小的变化,您也可以保持居中,这是您目前没有的。
  • 啊,谢谢!这就说得通了。至于相对中心点的事情,你想把它编辑成你的答案吗?听起来不错,但我不知道该怎么做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2014-09-30
  • 2013-05-04
相关资源
最近更新 更多