如何在QML中使一个项目在圆圈内拖动



下面的代码允许在矩形区域内拖动小红色矩形,该区域由最小和最大拖动值定义。

我想让它一直延伸到父矩形的边界,它的半径是100,这意味着它现在是一个圆

如何在QML中使一个项目在圆圈内拖动?

Window {
    width: 200; height: 200; visible: true
    Rectangle
    {
        x: 10; y: 10
        width: 200; height: 200
        radius: 100
        color: "blue"
        Rectangle {
            x: 10; y: 10
            width: 20; height: 20
            color: "red"
            MouseArea
            {
                id: dragArea
                anchors.fill: parent
                drag.target: parent
                drag.minimumX : 20
                drag.maximumX : 150
                drag.minimumY : 20
                drag.maximumY : 150
            }
        }
    }
}

所以我花了一些时间来提供前面提到的更流畅的解决方案。

import QtQuick 2.5
import QtQuick.Window 2.2
Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    property int radius: 100
    Rectangle {
        id: circle
        width: 2 * radius
        height: 2 * radius
        radius: root.radius
        color: 'blue'
    }
    Rectangle {
        id: mark
        width: 20
        height: 20
        x: (dragObj.dragRadius <= root.radius ? dragObj.x : root.radius + ((dragObj.x - root.radius) * (root.radius / dragObj.dragRadius))) - 10
        y: (dragObj.dragRadius <= root.radius ? dragObj.y : root.radius + ((dragObj.y - root.radius) * (root.radius / dragObj.dragRadius))) - 10
        color: 'red'
        MouseArea {
            id: markArea
            anchors.fill: parent
            drag.target: dragObj
            onPressed: {
                dragObj.x = mark.x + 10
                dragObj.y = mark.y + 10
            }
        }
    }
    Item {
        id: dragObj
        readonly property real dragRadius: Math.sqrt(Math.pow(x - root.radius, 2) + Math.pow(y - root.radius, 2))
        x: root.radius
        y: root.radius
        onDragRadiusChanged: console.log(dragRadius)
    }
}

我使用dragObj来避免拖动位置的限制。它从圆心张成一个向量。只要dragObj本身包含在圆圈中,我将使用它的位置作为标记的位置。
但是一旦它离开圆,我将把向量投影到圆上,所以它将保持在限制范围内。

为了确保每次拖动在标记上再次开始,我将重置dragObj的位置到标记的位置,当鼠标再次按下时(新拖动事件的先决条件)

玩得开心

有点晚了,但我准备参加一个小测验。

这是一个不完美的解决方案,有一些缺陷。

import QtQuick 2.5
import QtQuick.Window 2.2
Window {
    width: 400; height: 400; visible: true
    Rectangle
    {
        x: 10; y: 10
        width: 200; height: 200
        radius: 100
        color: "blue"
        Rectangle {
            x: 10; y: 10
            width: 20; height: 20
            color: "red"
            MouseArea
            {
                id: dragArea
                anchors.fill: parent
                drag.target: parent
                drag.minimumX : Math.ceil(100 - Math.sqrt(200 * parent.y - Math.pow(parent.y, 2)))
                drag.maximumX : Math.floor(Math.sqrt(200 * parent.y - Math.pow(parent.y, 2)) + 100)
                drag.minimumY : Math.ceil(100 - Math.sqrt(200 * parent.x - Math.pow(parent.x, 2)))
                drag.maximumY : Math.floor(Math.sqrt(200 * parent.x - Math.pow(parent.x, 2)) + 100)
            }
        }
    }
}

这个想法是,你根据y和x的当前值计算x和y的最大值和最小值(所以max-x取决于电流-y, max-y取决于电流-x)

后面的函数是:(r - y)² + (r - x)² = r²

我没有合并的是小的可拖动矩形的尺寸。所以我只强制左上角保持在圆的边界内。然而,这应该很容易适应。为了说明这一点,假设一个圆,矩形宽度/高度的一半减去半径,并将其移动矩形宽度/高度的一半。

另一个缺陷是,如果我达到一个限制(顶部,左侧,右侧,底部)矩形可能会闪烁,并且不能平滑地跟随鼠标。

为了解决这个问题,你可以使用一个不可见的对象作为助手,它可以自由地在周围绘制,然后你使用它的位置来计算显示的红色矩形的位置。

也许我以后也会为此添加一个实现。

最新更新