Skip to content

Instantly share code, notes, and snippets.

@Serhg94
Created June 16, 2021 15:21
Show Gist options
  • Save Serhg94/5e6d9e966a5958f0402b7e25f662372c to your computer and use it in GitHub Desktop.
Save Serhg94/5e6d9e966a5958f0402b7e25f662372c to your computer and use it in GitHub Desktop.
Map with drag and scale from image. With interactive marks. (like built-in type Map, but notGIS)
import QtQuick 2.12
Rectangle {
id: root
visible: true
anchors.fill: parent
color: "black"
property var animateDuration: 90
Flickable {
id: flick
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
contentWidth: Math.max(map.width * map.scale, width)
contentHeight: Math.max(map.height * map.scale, height)
Behavior on contentX { NumberAnimation { duration: root.animateDuration } }
Behavior on contentY { NumberAnimation { duration: root.animateDuration } }
MouseArea {
anchors.fill: parent
hoverEnabled: true
onWheel: {
if (wheel.modifiers & Qt.ControlModifier) {
map.rotation += wheel.angleDelta.y / 120 * 5;
if (Math.abs(map.rotation) < 4)
map.rotation = 0;
} else {
map.rotation += wheel.angleDelta.x / 120;
if (Math.abs(map.rotation) < 0.6)
map.rotation = 0;
var oldWidth = flick.contentWidth
var oldHeight = flick.contentHeight
var newScale = map.scale + map.scale * wheel.angleDelta.y / 120 / 10;
console.log(flick.contentWidth/oldWidth)
flick.contentX = flick.contentWidth === flick.width ? 0 : mouseX * map.width * newScale/oldWidth - flick.width / 2
flick.contentY = flick.contentHeight === flick.height ? 0 : mouseY * map.height * newScale/oldHeight - flick.height / 2
//flick.contentX = flick.contentWidth === flick.width ? 0 : mouseX - (flick.width / 2) * map.scale
//flick.contentY = flick.contentHeight === flick.height ? 0 : mouseY- (flick.height / 2) * map.scale
map.scale = newScale;
}
}
onPressed: {
mouse.accepted = false;
}
onReleased: {
mouse.accepted = false;
}
}
Image {
Behavior on scale { NumberAnimation { duration: root.animateDuration } }
id: map
transformOrigin: Item.Center
anchors.centerIn: parent
source: root.mapObj.image
antialiasing: true
Repeater {
model: mapObj.getItems()
Rectangle {
id: icon
property var itemObj: modelData
anchors.centerIn: parent
anchors.horizontalCenterOffset: itemObj.x - map.sourceSize.width / 2
anchors.verticalCenterOffset: itemObj.y - map.sourceSize.height / 2
width: itemObj.width
height: itemObj.height
border.color: itemObj.color
border.width: itemObj.border
smooth: true
antialiasing: true
Image {
id: image
scale: Math.max(parent.width, parent.height) / Math.max(sourceSize.width, sourceSize.height)
anchors.centerIn: parent
fillMode: Image.Pad
source: parent.itemObj.icon
antialiasing: true
}
MouseArea {
hoverEnabled: true
anchors.fill: parent
scrollGestureEnabled: false // 2-finger-flick gesture should pass through to the Flickable
onPressed: {
parent.itemObj.doAction()
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment