117 lines
3.8 KiB
QML
117 lines
3.8 KiB
QML
|
import QtQuick
|
||
|
import AntiClipSettings
|
||
|
|
||
|
Item {
|
||
|
id: root
|
||
|
property int dargWidth: 10
|
||
|
property var openDoorAreaPoints: []
|
||
|
Image {
|
||
|
id: image
|
||
|
anchors.centerIn: parent
|
||
|
cache: false
|
||
|
fillMode: Image.PreserveAspectFit
|
||
|
source: "image://videoframe/"
|
||
|
property real aspectRatio: 16 / 9
|
||
|
width: Math.min(root.width, root.height * aspectRatio)
|
||
|
height: width / aspectRatio
|
||
|
|
||
|
Canvas {
|
||
|
id: canvas
|
||
|
anchors.fill: parent
|
||
|
onPaint: {
|
||
|
var ctx = canvas.getContext("2d")
|
||
|
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
||
|
if (openDoorAreaPoints.length > 0) {
|
||
|
ctx.strokeStyle = "red"
|
||
|
ctx.lineWidth = 2
|
||
|
|
||
|
ctx.beginPath()
|
||
|
let point = scaledPoint(openDoorAreaPoints[0],
|
||
|
width, height)
|
||
|
ctx.moveTo(point.x, point.y)
|
||
|
for (var i = 1; i < openDoorAreaPoints.length; i++) {
|
||
|
point = scaledPoint(openDoorAreaPoints[i],
|
||
|
width, height)
|
||
|
ctx.lineTo(point.x, point.y)
|
||
|
}
|
||
|
ctx.closePath()
|
||
|
ctx.stroke()
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Repeater {
|
||
|
id: repeater
|
||
|
model: openDoorAreaPoints
|
||
|
delegate: Rectangle {
|
||
|
width: dargWidth
|
||
|
height: dargWidth
|
||
|
color: "red"
|
||
|
x: scaledPoint(modelData, canvas.width,
|
||
|
canvas.height).x - width / 2
|
||
|
y: scaledPoint(modelData, canvas.width,
|
||
|
canvas.height).y - height / 2
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MouseArea {
|
||
|
anchors.fill: parent
|
||
|
property int draggedPointIndex: -1
|
||
|
onPressed: mouse => {
|
||
|
for (var i = 0; i < openDoorAreaPoints.length; i++) {
|
||
|
let point = scaledPoint(openDoorAreaPoints[i],
|
||
|
canvas.width,
|
||
|
canvas.height)
|
||
|
if (isInside(mouse.x, mouse.y, point)) {
|
||
|
draggedPointIndex = i
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
onReleased: {
|
||
|
draggedPointIndex = -1
|
||
|
}
|
||
|
onPositionChanged: mouse => {
|
||
|
if (draggedPointIndex >= 0) {
|
||
|
openDoorAreaPoints[draggedPointIndex] = standardPoint(
|
||
|
Qt.point(mouse.x, mouse.y),
|
||
|
canvas.width, canvas.height)
|
||
|
canvas.requestPaint()
|
||
|
repeater.model = openDoorAreaPoints
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function isInside(x, y, point) {
|
||
|
let edge = dargWidth / 2
|
||
|
return x >= point.x - edge && x <= point.x + edge
|
||
|
&& y >= point.y - edge && y <= point.y + edge
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 转换为显示画点
|
||
|
function scaledPoint(point, width, height) {
|
||
|
let x = point.x * width / 640
|
||
|
let y = point.y * height / 360
|
||
|
return Qt.point(x, y)
|
||
|
}
|
||
|
|
||
|
function standardPoint(point, width, height) {
|
||
|
// 转换为设备画点(640x360)
|
||
|
let x = point.x * 640 / width
|
||
|
let y = point.y * 360 / height
|
||
|
return Qt.point(x, y)
|
||
|
}
|
||
|
|
||
|
Connections {
|
||
|
target: App
|
||
|
function onNewVideoFrame() {
|
||
|
image.source = ""
|
||
|
image.source = "image://videoframe/"
|
||
|
}
|
||
|
function onCurrentOpenDoorAreaPointsChanged() {
|
||
|
canvas.requestPaint()
|
||
|
}
|
||
|
}
|
||
|
}
|