Animation between images



  • Hello,

    I have a little qml that show an image based on some events from c++ backend. I created some states and for each state I have have set the properties for every single image to obtain the effect I want.

    But my qml code looks ugly. I want simple as active image slide to left while at the same time next image to show slide from right side (800px) to left (0px)

    I have read QML Repeater but it doesn't accept an array of image objects.

    How would you do that? I have tried also to set the target an image object but it doesn't seem to work.

    Can you point me some steps?

    Thank you

    import QtQuick 2.4
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 800; height: 480
    
        Rectangle {
            id: page
            state: msg.author
            width: 800; height: 480
            color: "#FEDC32"
    
            Text {
                id: tutorial
                z: 100
                width: 100; height: 100
                text: msg.author    // invokes Message::author() to get this value
    
                Component.onCompleted: {
                    msg.author = "Jonah"  // invokes Message::setAuthor()
                }
    
                function teste(){
                    msg.author = "teste2"
                }
            }
    
            Text {
                id: tutorial2
                z: 100
                y: 50
                width: 100; height: 100
                text: msg.debug    // invokes Message::author() to get this value
            }
    
            states: [
                // This adds a second state to the container where the rectangle is farther to the right
    
                State { name: "quarto"
                    PropertyChanges {
                        target: quartoImage
                        x: 0
                    }
                    PropertyChanges {
                        target: mainImage
                        x: -800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "sala"
                    PropertyChanges {
                        target: salaImage
                        x: 0
                    }
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 800
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "main"
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 0
                    }
                    PropertyChanges {
                        target: escImage
                        x: -800
                    }
                },
                State { name: "esc"
                    PropertyChanges {
                        target: quartoImage
                        x: 800
                    }
                    PropertyChanges {
                        target: salaImage
                        x: -800
                    }
                    PropertyChanges {
                        target: mainImage
                        x: 800
                    }
                    PropertyChanges {
                        target: escImage
                        x: 0
                    }
                }
            ]
    
            transitions: [
                Transition {
                    from: "main"; to: "quarto";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "quarto"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "main"; to: "sala";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "sala"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "main"; to: "esc";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                },
                Transition {
                    from: "esc"; to: "main";// reversible: true
                    ParallelAnimation {
                        NumberAnimation { properties: "x"; duration: 500; easing.type: Easing.InOutQuad }
                        ColorAnimation { duration: 500 }
                    }
                }
    
            ]
    
            MouseArea {
                x: 0
                y: 0
                width: 399;
                height: 480;
                onClicked: { console.log(page.state+"->"); page.state = "sala"; console.log(page.state) }
            }
    
            MouseArea {
                x: 401
                y: 0
                width: 399;
                height: 480;
                onClicked: { console.log(page.state+"->"); page.state = "quarto"; console.log(page.state) }
            }
    
            Image {
                id: mainImage
                source: "qrc:/ikea.jpg"
                anchors.verticalCenter: page.verticalCenter
            }
    
            Image {
                id: salaImage
                source: "qrc:/sala.jpg"
                anchors.verticalCenter: page.verticalCenter
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log();console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
            Image {
                id: quartoImage
                source: "qrc:/quarto.jpg"
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
            Image {
                id: escImage
                source: "qrc:/esc.jpg"
    
                MouseArea {
                    anchors.fill: parent;
                    onClicked: { console.log(page.state+"->"); page.state = "main"; console.log(page.state) }
                }
            }
    
        }
    
    }
    
    


  • Use ListView to show a list of images.

    import QtQuick 2.4
    
    Item {
    	id: root
    
    	ListView {
    		anchors.fill: parent
    
    		orientation: ListView.Horizontal // content will move horizontally when scrolling
    		snapMode: ListView.SnapOneItem // scrolling won't stop at the middle of an image
    		interactive: false // is not scrollable with mouse or keyboard arrows
    
    		delegate: Item {
    			width: root.width // if the image is smaller than the window, the next image will be still out of the screen
    
    			Image {
    				source: modelData
    			}
    		}
    
    		model: [
    			"1.jpeg",
    			"2.jpeg",
    			"3.jpeg",
    			"4.jpeg",
    			"5.jpeg"
    		]
    
    		MouseArea {
    			anchors.fill: parent
    			onClicked: parent.currentIndex += 1 // scroll to next when clicked
    		}
    	}
    }
    


  • @devel Thank you for the example :)
    However I want to be able to change from 1.jpg to 3.jpg per example. So all the images that aren't on center should be ready to show.



  • A bit hacky solution with Path. I'm not sure that PathView guarantees exact positioning of the elements. Maybe it's time to go back to the PropertyAnimations that you were doing before.

    import QtQuick 2.4
    
    Item {
    	id: root
    
    	PathView {
    		anchors.fill: parent
    
    		interactive: false
    
    		model: 2 // will hold 2 empty images
    
    		delegate: Item {
    			width: root.width
    
    			property alias source: img.source
    
    			Image {
    				id: img
    			}
    		}
    
    		path: Path {
    			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
    			startY: 0
    			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item will slide to here)
    		}
    
    		MouseArea {
    			anchors.fill: parent
    			onClicked: {
    				parent.currentIndex += 1
    				parent.currentItem.source = "4.jpeg"
    			}
    		}
    	}
    }
    

    Also, to see what's really going on, I've added some coloured rectangles. Launch the next code with QSG_VISUALIZE=overdraw environment variable to see the stuff that's outside the window.

    Command line:

    $ QSG_VISUALIZE=overdraw qmlscene path.qml
    

    Code (almost the same):

    import QtQuick 2.4
    
    Item {
    	id: root
    
    	PathView {
    		anchors.fill: parent
    
    		interactive: false
    
    		model: 2 // will hold 2 empty images
    
    		delegate: Rectangle {
    			height: 50
    			color: ["red","blue"][modelData]
    
    			width: root.width
    
    			property alias source: img.source
    
    			Image {
    				id: img
    			}
    		}
    
    		path: Path {
    			startX: root.width * 1.5 // starting point is the middle of the imaginary screen on the right (center of the next Item is here)
    			startY: 0
    			PathLine { x: -root.width * 0.5; y: 0 } // destination point is the middle of the imaginary screen on the left (center of the current item eill slide to here)
    		}
    
    		MouseArea {
    			anchors.fill: parent
    			onClicked: {
    				parent.currentIndex += 1
    				parent.currentItem.source = "4.jpeg"
    			}
    		}
    	}
    }
    


  • @devel I understand the idea. Now I'm trying to set the next image from C++. I was looking on how to change the model from c++ ( http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html ) but after the PathView is created any changes on the model from C++ doesn't take any action on QML :s



  • The model-view is when we give all images to ListView/PathView (or something like that) and then let user to manipulate them.

    The last example with PathView isn't a real model-view. It's a hack to show just one image and to be able to change it with a sliding effect.

    It's possible to control the image via a property like that for example:

    import QtQuick 2.4
    
    Item {
        id: root
    
        property url imageSource
    
        onImageSourceChanged: {
            pathView.currentIndex += 1
            pathView.currentItem.source = imageSource
        }
    
        PathView {
            id: pathView
    
            anchors.fill: parent
    
        ...
    

    C++ can definitively bind something different to this new imageSource property.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.