How to make an item drag inside a circle in QML?

前端 未结 2 1463
自闭症患者
自闭症患者 2021-02-10 15:08

Below code allows the small red coloured rectangle to be dragged in an area which is a rectangle defined by minimum and maximum drag values.

I want it to go on only up t

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-10 15:55

    So I found some time to provide the aforementioned smoother solution.

    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)
        }
    }
    

    I use the dragObj to avoid the limitations of my dragging position. This spans a vector from the center of the circle. As long as the dragObj itself is contained in the circle, I will use it's position as the position of the marker.
    But once it leaves the circle, I will project the vector on the circle, so it will stay within the limits.

    To ensure, that every drag starts again on the mark, I will reset the position of the dragObj to the position of the mark, when ever the mouse is pressed again (precondition for a new drag-event)

    Have fun with it.

提交回复
热议问题