Brykyz
Brykyz

Reputation: 657

Zoomable flickable (map-like) in QML

I am trying to make component, which allows me to move with Flickable and zoom it, similiar to QML component Map, except there will be border for user (which Flickable has by default).

Currently, I have this

Flickable {
    id: flickArea
    width: parent.width
    height: parent.height
    contentWidth: inner.width *  slider.value
    contentHeight: inner.height * slider.value
    Image {
        transform: Scale {
            origin.x: parent.width /2
            origin.y: parent.height/2
            xScale:  slider.value
            yScale: slider.value
        }

        id: inner
        width: parent.contentWidth
        anchors.centerIn: parent
        source: "file:/home/username/imgs/test"
    }
}

but it doesn't work as expected (there is white border around, and zoom isn't centered).

What am I doing wrong? Should I use Flickable, or is there any more suitable component?

Upvotes: 0

Views: 1662

Answers (1)

Julien Déramond
Julien Déramond

Reputation: 599

Your source code is not complete and doesn't allow to understand exactly the problem.

So, I'm going to assume that:

  1. the white borders mentioned are the white surface displayed when the surface is dragged beyond the Flickable's boundaries.

  2. the slider id refers to a Slider item.

The following code could help:

import QtQuick 2.9
import QtQuick.Controls 1.4

Item {
    width: 1280
    height: 720

    Flickable {
        id: flickArea
        anchors.fill: parent
        focus: true
        contentWidth: Math.max(inner.width * slider.value, width)
        contentHeight: Math.max(inner.height  * slider.value, height)
        anchors.centerIn: parent
        boundsBehavior: Flickable.StopAtBounds
        contentX: contentWidth === width ? 0 : inner.width * slider.value / 2 - flickArea.width / 2
        contentY: contentHeight === height ? 0 : inner.height * slider.value / 2 - flickArea.height / 2

        Image {
            id: inner
            scale: slider.value
            transformOrigin: Item.Center
            anchors.centerIn: parent
            source: "Ba_b_do8mag_c6_big.png"
        }
    }

    Slider {
        id: slider
        value: 2
        orientation: Qt.Vertical
        anchors {
            bottom: parent.bottom
            right: parent.right
            margins: 50
        }
    }
}

Here, the white borders are not displayed anymore thanks to the boundsBehavior: Flickable.StopAtBounds.

In my example, when the slider is used, the zoom is always centered. The user can flick the surface as soon as the rendered image is bigger than the size of the window.

However, even if the user moves in the area, the zoom will always be centered. The movement is not saved.

The image used is downloadable here: https://commons.wikimedia.org/wiki/File:Ba_b_do8mag_c6_big.png_

Upvotes: 3

Related Questions