How to implement “Snap While Dragging” behavior in QML?
Unsolved
QML and Qt Quick
-
I'm looking to achieve a "snap while dragging" behavior in QML. Specifically, within my example below, when the element being dragged (red column) reaches a location on the x axis that is inside the "snap area" (orange column), it snaps to the middle of the snap area and sticks there until the mouse pointer is again outside the snap area, at which point the dragged element should snap to the current position of the mouse pointer and the drag continues on it's way. Here is what I have so far:
import QtQuick 2.12 import QtQuick.Window 2.12 Window { id: main_window width: 640 height: 480 visible: true visibility: Window.Maximized property double x_location: square.x property double y_location: square.y property double start_x_of_snap_area: snap_area.x property double end_x_of_snap_area: snap_area.x + snap_area.width property bool is_handlebar_inside_snap_area: false onX_locationChanged: function () { if (x_location >= start_x_of_snap_area && square.x + square.width <= end_x_of_snap_area) { is_handlebar_inside_snap_area = true } else { is_handlebar_inside_snap_area = false } } onIs_handlebar_inside_snap_areaChanged: function () { if (is_handlebar_inside_snap_area === true) { console.log(dragArea.drag.target) dragArea.drag.target = null square.anchors.horizontalCenter = snap_area.horizontalCenter } } Text { y: 0 text: "start_x_of_snap_area: " + start_x_of_snap_area font.pixelSize: 30 } Text { y: 50 text: "end_x_of_snap_area: " + end_x_of_snap_area font.pixelSize: 30 } Text { y: 100 text: "is_handlebar_inside_snap_area: " + is_handlebar_inside_snap_area font.pixelSize: 30 } Rectangle { id: snap_area height: parent.height width: 200 anchors.centerIn: parent color: 'orange' Text { text: "snap area" font.pixelSize: 30 anchors.centerIn: parent } } Rectangle { id: square width: 50 height: main_window.height color: 'red' opacity: .7 Drag.active: dragArea.drag.active Text { text: 'x: ' + x_location + ' y: ' + y_location font.pixelSize: 10 color: 'white' anchors.centerIn: parent font.family: 'Arial' } MouseArea { id: dragArea drag { target: parent axis: "XAxis" minimumX: 0 maximumX: main_window.width - square.width } anchors.fill: parent cursorShape: Qt.SizeAllCursor } } }
Some problems with the above code is once the snap happens, its stuck. Also, if you move the mouse pointer really fast over the snap area the function doesn't fire quick enough to give satisfactory results (it doesn't work at all).