Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML Image Comparison Slider
Forum Updated to NodeBB v4.3 + New Features

QML Image Comparison Slider

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 2.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    stcorp
    wrote on last edited by
    #1

    Hi guys. I'm trying to create an image comparison slider item in QML, something similar to Juxtapose.

    Its going pretty well, and I have a working QML item, however I have a few issues that I haven't been able to resolve yet and I was wondering if anyone had any ideas to solve them.

    When I set the background of the two images to be a solid color, everything works fine:

    0_1498574031243_Screenshot_20170627_163220.png

    However, when I set the background of the images to be transparent, a problem arises

    0_1498574061838_Screenshot_20170627_163248.png

    As you can see, the right image now bleeds over to the left side.

    From the code, it is relatively apparent why this happens, since the right side image just spans the entire width, and the left image is pasted on top of it. However, I haven't been able to thing of a solution that will work. If I anchor the right hand side image to the divider, similar to what I did for the left hand side image, then the image will move when I move the slider, which is undesired.

    Here is the code:

    ImageComparison.qml

    import QtQuick 2.0
    
    Item {
        id: root
        property var divColor: "white"
        property var bgColor: "transparent"
        property var leftSource: "http://images.clipartpanda.com/rocket-clipart-nicubunu_Toy_rocket.png"
        property var rightSource: "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/SNice.svg/1200px-SNice.svg.png"
    
        // When the size of the item is changed, we want to keep the divider at the same
        // relative position. If the relative position is undefined, we default to 0.5
        onWidthChanged: {
            div.x = div.relX ? width*div.relX : width*0.5
        }
    
        // Allows you to click anywhere on the pictures to move the divider
        MouseArea {
            anchors.fill: parent
            cursorShape: Qt.PointingHandCursor
            onClicked: div.x = mouseX
        }
    
        // Right image. It is at the bottom, and fills the entire item
        Rectangle {
            anchors.fill: parent
            color: bgColor
    
            Image {
                source: rightSource
                anchors.fill: parent
            }
        }
    
        // Left image. It is overlayed on the right image, and fills from the left to the divider
        Rectangle {
            anchors {
                left: parent.left
                right: div.left
                top: parent.top
                bottom: parent.bottom
            }
            color: bgColor
            clip: true
            // The actual image is actually just as large as the containing item
            Image {
                width: root.width
                height: root.height
                source: leftSource
            }
        }
    
        // The divider
        Rectangle {
            id: div
            property double relX: x/root.width
            x: root.width/2
            width: 5
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            color: divColor
            border.color: "black"
            border.width: 1
    
            MouseArea {
                id: dragArea
                anchors {
                    top: parent.top
                    bottom: parent.bottom
                    right: rightArrow.right
                    left: leftArrow.left
                }
    
                drag.target: parent
                cursorShape: Qt.SizeHorCursor
                hoverEnabled: true
            }
    
            Drag.active: dragArea.drag.active
            // Keep divider from going outside the limits
            onXChanged: {
                if (x > parent.width - width) x = parent.width - width
                if (x < 0) x = 0
            }
    
            // Right arrow
            Canvas {
                id: rightArrow
                anchors {
                    left: parent.right
                    verticalCenter: parent.verticalCenter
                    leftMargin: dragArea.containsMouse ? 5 : 2
                }
                width: 20
                height: 20
                opacity: 0.5
                onPaint: {
                    var ctx = getContext("2d");
                    ctx.fillStyle = divColor;
                    ctx.strokeStyle = "black";
                    ctx.beginPath();
                    ctx.moveTo(0,0);
                    ctx.lineTo(width,height/2);
                    ctx.lineTo(0,height);
                    ctx.closePath();
                    ctx.fill();
                    ctx.stroke();
                }
                Behavior on anchors.leftMargin { PropertyAnimation{ duration: 150} }
            }
    
            // Left arrow
            Canvas {
                id: leftArrow
                anchors {
                    right: parent.left
                    verticalCenter: parent.verticalCenter
                    rightMargin: dragArea.containsMouse ? 5 : 2
                }
                width: 20
                height: 20
                opacity: 0.5
                onPaint: {
                    var ctx = getContext("2d");
                    ctx.fillStyle = divColor
                    ctx.strokeStyle = "black";
                    ctx.beginPath();
                    ctx.moveTo(width,0);
                    ctx.lineTo(0,height/2);
                    ctx.lineTo(width,height);
                    ctx.closePath();
                    ctx.fill();
                    ctx.stroke();
                }
                Behavior on anchors.rightMargin { PropertyAnimation{ duration: 150} }
            }
        }
    
    }
    

    And this is a simple QML file which uses the ImageComparison item

    main.qml (in same directory as ImageComparision.qml)

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import "." as CustomControls
    
    ApplicationWindow {
        id: window
        visible: true
        width: 500
        height: 500
    
        Rectangle {
            color: "red"
            anchors.fill: parent
    
            CustomControls.ImageComparison {
                anchors.centerIn: parent
                width: window.width-100
                height: window.height-100
            }
        }
    }
    
    

    If anyone has any ideas on how to solve this issue, or any other general improvements to the code, please tell me :)

    1 Reply Last reply
    0
    • S Offline
      S Offline
      stcorp
      wrote on last edited by
      #2

      Here is a nice animation showing how it looks :)

      alt text

      raven-worxR 1 Reply Last reply
      0
      • S stcorp

        Here is a nice animation showing how it looks :)

        alt text

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @stcorp
        i would simply use a opacity mask on both images.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        S 1 Reply Last reply
        1
        • raven-worxR raven-worx

          @stcorp
          i would simply use a opacity mask on both images.

          S Offline
          S Offline
          stcorp
          wrote on last edited by
          #4

          @raven-worx Yeah, that would probably work. I forgot those existed. Thanks for thinking along

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved