MouseArea Inertia (for Dummies)

Originally posted on QuicKing, the Kingdom of QML Workaround, the blog I kept in 2011 and 2012. Here’s how that kingdom started and ended.

This is a simple piece of code to give your draggable objects smoother motion. It won’t win a Nobel Prize in physics, but if you don’t want to install a giant component like Box2D, it’s enough for simple movements.

Use it like a MouseArea

Rectangle{
    id: rect
    width: 100
    height: 100

    Fisica {
         anchors.fill: parent
         drag.target: rect
         drag.axis: Drag.XandYAxis
         drag.minimumX: 0
         drag.maximumX: container.width - rect.width
         drag.minimumY: 0
         drag.maximumY: container.height - rect.height
     }
}

You need a Fisica.qml with this code.

Quick physics component (Fisica.qml)

import QtQuick 1.0

MouseArea {
    id: fis

    onReleased: startFisica()

    /* Get last positions */
    property int oldX
    property int oldY
    SequentialAnimation{
        id: loadFisicaAnim
        loops: -1; running: pressed
        ScriptAction{
            script: {
                fis.oldX = drag.target.x
                fis.oldY = drag.target.y
                initFisica.stop()
            }
        }
        // get positions 200ms before release
        PauseAnimation { duration: 200 }
    }

    /* Calculate new positions */
    property int newX: drag.target.x + (drag.target.x - fis.oldX)
    property int newY: drag.target.y + (drag.target.y - fis.oldY)
    function startFisica(){
        // stop some animation
        loadFisicaAnim.stop()
        // check drag limits
        initFisica.xTo=(fis.newX > drag.maximumX)?drag.maximumX:(fis.newX < drag.minimumX)?drag.minimumX:fis.newX
        initFisica.yTo=(fis.newY > drag.maximumY)?drag.maximumY:(fis.newY < drag.minimumY)?drag.minimumY:fis.newY
        // start animation
        initFisica.start()
    }
    SequentialAnimation{
        id: initFisica
        property int xTo
        property int yTo
        ParallelAnimation{
            PropertyAnimation{ target:drag.target; property: "x"; to: initFisica.xTo; duration: 500; easing.type: "OutSine"  }
            PropertyAnimation{ target:drag.target; property: "y"; to: initFisica.yTo; duration: 500; easing.type: "OutSine"  }
        }
    }
}

Or download the project and be happy! 😀

GitHub project

github.com/diegodotta/qml-inertia

You may also enjoy…

All posts →