D
D
Deterok2015-04-16 23:17:01
Qt
Deterok, 2015-04-16 23:17:01

How to properly implement relative zoom in QML?

I posted this code:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

    menuBar: MenuBar {
        Menu {
            title: qsTr("&File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: messageDialog.show(qsTr("Open action triggered"));
            }
            MenuItem {
                text: qsTr("E&xit")
                onTriggered: Qt.quit();
            }
        }
    }

    Item {
        anchors.fill: parent
        width: 640
        height: 480

        Rectangle {
            id: rectangle1
            x: 220
            y: 140
            width: 200
            height: 200
            color: "#5e56e4"

            Rectangle {
                id: rectangle2
                x: 50
                y: 50
                width: 100
                height: 100
                color: "#7bfb7b"
            }

            transform: [Scale {
                    id: scaleRect

                    Behavior on xScale {
                        NumberAnimation {duration: 300}
                    }

                    Behavior on yScale {
                        NumberAnimation {duration: 300}
                    }
                }
            ]
        }

        MouseArea {
            id: mouseArea1
            anchors.fill: parent

            onWheel: {
                var origin = mapToItem(rectangle1, wheel.x, wheel.y)
                scaleRect.origin.x = origin.x
                scaleRect.origin.y = origin.y
                scaleRect.xScale += wheel.angleDelta.y / 120
                scaleRect.yScale += wheel.angleDelta.y / 120
                console.log(origin.x, origin.y, scaleRect.xScale)
            }
        }
    }


    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
}

Planned:
  1. Moved the cursor to the corner of the inner rect
  2. Turned the mouse wheel
  3. The picture has increased / decreased relative to the cursor (i.e., relative to the cursor, the corner should remain in place)

In fact:
The angle leaves and can be strong
Explain why this is so, but rather how to correctly make relative zooming.
Antaŭdankon!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Pavel K, 2015-04-17
@Deterok

Because you don't remember the position of the cursor at the beginning of the scroll, and when the pointer moves during the scroll, a recalculation occurs. I think about it, I'll check it now.
And the use of origin is not true for relative scaling.
Something like that:

Item {
            anchors.fill: parent
            width: 640
            height: 480

            Rectangle {
                id: rectangle1
                x: 220
                y: 140
                width: 200
                height: 200
                color: "#5e56e4"

                Rectangle {
                    id: rectangle2
                    x: 50
                    y: 50
                    width: 100
                    height: 100
                    color: "#7bfb7b"
                }

                Behavior on x {
                     NumberAnimation {duration: 300}
                }
                Behavior on y {
                     NumberAnimation {duration: 300}
                }

                transform: [Scale {
                        id: scaleRect

                        Behavior on xScale {
                            NumberAnimation {duration: 300}
                        }

                        Behavior on yScale {
                            NumberAnimation {duration: 300}
                        }


                    }
                ]
            }

            MouseArea {
                id: mouseArea1
                anchors.fill: parent
                property double ratio: 0.5;

                onWheel: {
                    var origin = mapToItem(rectangle1, wheel.x, wheel.y)
                    var scale = (wheel.angleDelta.y < 0)? ratio : 1/ratio; //-- приближаем или отдаляем

                    //-- Рассчитываем на сколько сдвигать при маштабировании относительно текущей точки
                    var newX = origin.x * scaleRect.xScale;
                    var newY = origin.y * scaleRect.yScale;
                    rectangle1.x += (1-scale)*newX;
                    rectangle1.y += (1-scale)*newY;

                    scaleRect.xScale *=scale;
                    scaleRect.yScale *=scale;

                }
            }
        }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question