-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathLoadingOverlay.qml
More file actions
120 lines (101 loc) · 3.69 KB
/
Copy pathLoadingOverlay.qml
File metadata and controls
120 lines (101 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import QtQuick
import QtQuick.Controls
Popup {
id: root
// === 公共属性 ===
property string text: ""
property color textColor: "#1c1c1e" // iOS label
property color animationColor: "#007aff" // iOS systemBlue
property color cardBackgroundColor: "#F2F2F7F2" // iOS secondarySystemBackground (95% opacity)
property color dimColor: "#00000066" // 40% 黑色遮罩
property int animationSpeed: 100
// 动画几何参数 (与 LoadingIndicator.qml 同步)
property int dotCount: 8
property int dotRadius: 6
readonly property real _cardWidth: 220
readonly property real _animSize: 80
readonly property real _textSpacing: 16
// === 私有数据 (与 CircularProgressQuick 一致使用 privateData 命名) ===
QtObject {
id: privateData
property int currentFrame: 0
}
anchors.centerIn: parent
modal: true
focus: true
closePolicy: Popup.NoAutoClose
padding: 0
width: _cardWidth
background: Rectangle {
// 暗色遮罩
color: root.dimColor
}
// === 内容卡片 ===
contentItem: Rectangle {
id: card
width: root._cardWidth
implicitHeight: contentColumn.implicitHeight + 32 * 2
color: root.cardBackgroundColor
radius: 14 // iOS 卡片圆角
Column {
id: contentColumn
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
spacing: root._textSpacing
// === RotatingDots 动画 ===
Item {
width: root._animSize
height: root._animSize
anchors.horizontalCenter: parent.horizontalCenter
readonly property real _centerX: width / 2
readonly property real _centerY: height / 2
readonly property real _radius: Math.min(width, height) * 0.25
Repeater {
model: root.dotCount
Rectangle {
required property int index
width: root.dotRadius * 2
height: root.dotRadius * 2
radius: root.dotRadius
color: root.animationColor
readonly property real angle: 2 * Math.PI * index / root.dotCount - 2 * Math.PI * privateData.currentFrame / 60.0
readonly property real opacityValue: 0.3 + 0.7 * (Math.sin(angle + privateData.currentFrame * 0.1) + 1) / 2
x: parent._centerX + parent._radius * Math.cos(angle) - root.dotRadius
y: parent._centerY + parent._radius * Math.sin(angle) - root.dotRadius
opacity: opacityValue
}
}
}
// === 文本标签 ===
Text {
text: root.text
color: root.textColor
font.bold: true
font.pixelSize: 14
anchors.horizontalCenter: parent.horizontalCenter
visible: root.text !== ""
horizontalAlignment: Text.AlignHCenter
}
}
// === 动画定时器 ===
Timer {
id: animationTimer
interval: root.animationSpeed
running: root.visible
repeat: true
onTriggered: {
privateData.currentFrame = (privateData.currentFrame + 1) % 1000;
}
}
}
// === 公共方法 ===
function show(message) {
if (message !== undefined) {
text = message;
}
open();
}
function hide() {
close();
}
}