Как повернуть прямоугольник qml путем перетаскивания?

Я создаю таймер, где время может быть установлено путем перетаскивания часовой стрелки (с помощью сенсорного ввода или мыши). Для этой цели я определил элемент AnalogClockHand, как показано ниже,

AnalogClockHand.в QML

Rectangle {
    id: hand

    property alias rotationAngle: handRotation.angle

    x: (parent.width / 2) - (width / 2); y: (parent.height / 2) - height; z: 2
    width: units.gu(1); height: units.gu(14);
    radius: units.gu(1)
    color: Constants.coolGrey
    antialiasing: true

    transform: Rotation {
        id: handRotation

        origin { x: hand.width / 2; y: hand.height }    
        Behavior on angle {
            SpringAnimation { spring: 2; damping: 0.3; modulus: 360 }
        }
    }
}

в основном файле qml я использовал этот элемент и добавил к нему mouseArea, как показано ниже,

Основной Файл Qml

AnalogClockHand {
        id: secondHand

        z: parent.z - 1;
        height: units.gu(17); width:  units.gu(0.5)
        rotationAngle: seconds * 6;
        antialiasing: true;

        // Implements touch support
        MouseArea {
            id: timerbackmousearea

            property real truex: mouseX - parent.width/2
            property real truey: parent.height/2 - mouseY
            property real angle: Math.atan2(truex, truey)
            property real strictangle: parseInt(angle * 180 / Math.PI)
            property real modulo: strictangle % 6

            anchors.fill: parent
            preventStealing: true

            onPositionChanged: if (timerbackmousearea.angle < 0) {
                                   secondHand.rotationAngle = strictangle - modulo + 360;
                                   timerValue = parseInt(secondHand.rotationAngle/6);
                                   seconds = timerValue;
                               }
                               else {
                                   secondHand.rotationAngle = strictangle - modulo + 6;
                                   timerValue = parseInt(secondHand.rotationAngle/6);
                                   seconds = timerValue;
                               }
        }
    }

эта логика не работает должным образом и очень сильно шелушится. Поэтому нельзя установить время так же плавно. В конце дня, я пытаюсь реализовать что-то, как показано на рисунке ниже. Пользователь должен иметь возможность перемещать час, минуту или секунды, чтобы установить время.

есть ли лучшая логика кода, которую я мог бы реализовать ?

Примечание 1: я понимаю, что вторая рука очень мала на изображении, но это должно быть исправлено достаточно скоро.

enter image description here

1 ответов


Я бы сделал это так (я сделал более простой код, поскольку у меня нет компонентов Ubuntu Touch), но логика вращения здесь и угол второго преобразования тоже:

import QtQuick 2.0

Rectangle{
    id: root;
    width: 720;
    height: 480;
    color: "black";

    Item {
        id: container;
        width: 250;
        height: width;
        anchors.centerIn: parent;

        property real centerX : (width / 2);
        property real centerY : (height / 2);

        Rectangle{
            id: rect;
            color: "white";
            transformOrigin: Item.Center;
            radius: (width / 2);
            antialiasing: true;
            anchors.fill: parent;

            Rectangle {
                id: handle;
                color: "red";
                width: 50;
                height: width;
                radius: (width / 2);
                antialiasing: true;
                anchors {
                    top: parent.top;
                    margins: 10;
                    horizontalCenter: parent.horizontalCenter;
                }

                MouseArea{
                    anchors.fill: parent;
                    onPositionChanged:  {
                        var point =  mapToItem (container, mouse.x, mouse.y);
                        var diffX = (point.x - container.centerX);
                        var diffY = -1 * (point.y - container.centerY);
                        var rad = Math.atan (diffY / diffX);
                        var deg = (rad * 180 / Math.PI);
                        if (diffX > 0 && diffY > 0) {
                            rect.rotation = 90 - Math.abs (deg);
                        }
                        else if (diffX > 0 && diffY < 0) {
                            rect.rotation = 90 + Math.abs (deg);
                        }
                        else if (diffX < 0 && diffY > 0) {
                            rect.rotation = 270 + Math.abs (deg);
                        }
                        else if (diffX < 0 && diffY < 0) {
                            rect.rotation = 270 - Math.abs (deg);
                        }
                    }
                }
            }
        }
        Text {
            text: "%1 secs".arg (Math.round (rect.rotation / 6));
            font {
                pixelSize: 20;
                bold: true;
            }
            anchors.centerIn: parent;
        }
    }
}

работает отлично !


вывод для приведенного выше примера

enter image description here