Files
work-secretfile-selfcheck/UmiOCR-data/qt_res/qml/Widgets/Loading.qml

200 lines
7.8 KiB
QML
Raw Normal View History

// ==============================================
// =============== 加载中 动态图标 ===============
// ==============================================
import QtQuick 2.15
import QtGraphicalEffects 1.15 // 阴影
Item {
id: lRoot
property string text: "OCR..."
property real time: 700 // 动画间隔时间,毫秒
width: size_.smallText * 6
height: width
clip: true
property bool running: false // 是否运行动画
onVisibleChanged: {
if(visible) {
image.init()
cRoot.init()
running = qmlapp.enabledEffect // 启动动画
}
else {
running = false // 停止动画
}
}
// 主体
Panel {
anchors.fill: parent
color: theme.bgColor
// 图标
Item {
anchors.fill: parent
anchors.margins: size_.spacing * 2
anchors.topMargin: size_.spacing
Image {
id: image
source: "../../images/icons/dango_right.png"
mipmap: true // 启用高质量缩放
fillMode: Image.Stretch
property real p1x
property real p1y
property real pw
property real ph
property real sw
property real sh
property real p1w
property real p1h
property real p2x
property real p2y
property real p2w
property real p2h
property real pt: lRoot.time * 0.5
// 预计算变形动画参数
Component.onCompleted: {
// 父组件大小
pw=parent.width, ph=parent.height
// 图片原始大小
sw=sourceSize.width, sh=sourceSize.height
// 最高点
p1h=ph*0.9, p1w=p1h*(sw/sh)*0.9, p1y=0, p1x=(pw-p1w)*0.5
// 最低点
p2h=p1h*0.9, p2w=p1h*(sw/sh)*1.1, p2x=(pw-p2w)*0.5, p2y=ph-p2h
}
// 恢复初始状态
function init() {
if(qmlapp.enabledEffect) {
x=p2x, y=p2y
width=p2w, height=p2h
}
else {
height=ph, width=ph*(sw/sh)
y=0, x=(pw-width)*0.5
}
}
// 串行动画
SequentialAnimation{
id: animation
running: lRoot.running
loops: Animation.Infinite
ParallelAnimation {
NumberAnimation{ target:image; property:"x"; to:image.p1x; duration:image.pt; easing.type:Easing.OutCubic}
NumberAnimation{ target:image; property:"y"; to:image.p1y; duration:image.pt; easing.type:Easing.OutCubic}
NumberAnimation{ target:image; property:"width"; to:image.p1w; duration:image.pt; easing.type:Easing.OutCubic}
NumberAnimation{ target:image; property:"height"; to:image.p1h; duration:image.pt; easing.type:Easing.OutCubic}
}
ParallelAnimation {
NumberAnimation{ target:image; property:"x"; to:image.p2x; duration:image.pt; easing.type:Easing.InCubic}
NumberAnimation{ target:image; property:"y"; to:image.p2y; duration:image.pt; easing.type:Easing.InCubic}
NumberAnimation{ target:image; property:"width"; to:image.p2w; duration:image.pt; easing.type:Easing.InCubic}
NumberAnimation{ target:image; property:"height"; to:image.p2h; duration:image.pt; easing.type:Easing.InCubic}
}
}
}
}
// 下方文字动画
Item {
id: cRoot
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
// anchors.margins: size_.smallSpacing
height: size_.smallText
property var chars: []
property int time: lRoot.time
Component.onCompleted: {
let l = []
for(let i in lRoot.text)
l.push(lRoot.text[i])
chars = l
textTimer.max = l.length
}
// 恢复初始状态
function init() {
textTimer.now = 0
}
Timer {
id: textTimer
property int now: 0
property int max: 0
interval: cRoot.time
running: lRoot.visible
repeat: true
onTriggered: {
if(now===max-1)
now = 0
else
now++
}
}
Row {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
spacing: size_.smallText * 0.1
Repeater {
model: cRoot.chars
Text_ {
id: charT
property bool charShow: textTimer.now===index
font.pixelSize: size_.smallText
text: modelData
color: theme.specialTextColor
property real minOpa: 0.5
opacity: minOpa
property real sp: size_.smallSpacing
property real spMax: size_.smallSpacing * 1.5
anchors.bottom: parent.bottom
anchors.bottomMargin: sp
height: size_.smallText
onCharShowChanged: {
if(lRoot.running) {
if(charShow) caShow.running = true
else caHide.running = true
}
else {
anchors.bottomMargin = charShow ? spMax : sp
opacity = charShow ? 1 : minOpa
}
}
ParallelAnimation {
id: caShow
running: false
NumberAnimation {
target:charT; properties: "anchors.bottomMargin";
from: charT.sp; to: charT.spMax; duration:cRoot.time * 0.5;
easing.type:Easing.OutCubic;
}
NumberAnimation {
target:charT; properties: "opacity";
from: minOpa; to: 1; duration:cRoot.time * 0.5;
easing.type:Easing.OutCubic;
}
}
ParallelAnimation {
id: caHide
running: false
NumberAnimation {
target:charT; properties: "anchors.bottomMargin";
from: charT.spMax; to: charT.sp;
easing.type:Easing.InQuart; duration:cRoot.time;
}
NumberAnimation {
target:charT; properties: "opacity";
from: 1; to: minOpa; duration:cRoot.time;
easing.type:Easing.InQuart;
}
}
}
}
}
}
}
}