Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Try to scale image with mouse wheel and use mouse pos as center



  • Hi all

    I tried to develop an image viewer and use mouse wheel to scale up or down the image

    It is quite easy to make image scale up by setting image.scale but it limits to the transformOrigin enum. And in my case, I want to scale using current mouse pos as center. That means the pixel under cursor is never move and other pixel scaled.

    my code goes:

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Layouts 1.12
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Rectangle {
            id: imageArea
            anchors.fill: parent
            color: "black"
            Image {
                id: ximage
                source: "test.png"
                cache: false
                x:(parent.width-ximage.width)/2
                y:(parent.height-ximage.height)/2
            }
    
            MouseArea {
                anchors.fill: ximage
                hoverEnabled:true
                drag.target: ximage
                drag.minimumX: (ximage.width>imageArea.width)?(imageArea.width-ximage.width):0
                drag.maximumX: (ximage.width>imageArea.width)?0:(imageArea.width-ximage.width)
                drag.minimumY: (ximage.height>imageArea.height)?(imageArea.height-ximage.height):0
                drag.maximumY: (ximage.height>imageArea.height)?0:(imageArea.height-ximage.height)
    
                onWheel: {
                    var ratio = 0.95
                    if (mouseX<0 ||mouseY<0)  {
                           // ignore negative values, but it should never be negative?
    //                     console.log(containsMouse)
                        return
                    }
                    var relX = mouseX
                    var relY = mouseY
                    var oriX = ximage.x // save old image x
                    var oriY = ximage.y // save old image y
                    console.log(relX,relY)
                    console.log(ximage.x,ximage.y,ximage.width,ximage.height)
    
                    var delta = wheel.angleDelta.y / 120
                    if (delta>0){
                        // change image width and height would change image.x and image.y, so use the val saved before
                        ximage.width = ximage.width/ratio
                        ximage.height = ximage.height/ratio
                        ximage.x = oriX + (1-1/ratio)*relX
                        ximage.y = oriY + (1-1/ratio)*relY
                    } else {
                        ximage.width = ximage.width*ratio
                        ximage.height = ximage.height*ratio
                        ximage.x = oriX + (1-ratio)*relX
                        ximage.y = oriY + (1-ratio)*relY
    
                    }
                    console.log(ximage.x,ximage.y,ximage.width,ximage.height)
                    console.log(mouseX,mouseY) // mouse x and y are changed and invalid, which is strange, and it sometimes be negative value 
                }
            }
        }
    }
    

    my code works when the negative values are ignored. But as I support drag actions, when I drag the image and wheel, mouseX and mouseY sometimes are positive, which cannot be ignored by my code and make scale fail (the pixel under mouse cursor swift)

    I think there are serval solutions,
    1 keep mouseX,mouseY always valid by some methods?
    2 make transformOrigin support mouse pos?
    3 I wrote some wrong code and there is better way to fulfill my demand

    Seeking for help



  • I found solution:

    NEVER USE MOUSE.X OR MOUSE.Y IN WHEEL EVENT

    instead, use wheel.x and wheel.y



  • Thanks for posting your code/solution, this is exactly what I was looking for to compliment my weather dashboard.


Log in to reply