C
Qt Quick Ultralite 手表演示
/****************************************************************************** ** ** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Ultralite module. ** ** $QT_BEGIN_LICENSE:COMM$ ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** $QT_END_LICENSE$ ** ******************************************************************************/import QtQuick 2.15 import QtQuickUltralite.Extras 2.0 import Watch 1.0 Rectangle { id: root height: Theme.appHeight width: Theme.appWidth color: Theme.backgroundColor property bool onScreen: false property bool offScreen: false readonly property int heartbeatDuration: 130 readonly property int heartImgWidth: 39 readonly property int heartImgHeight: 34 readonly property int introDuration: 200 readonly property int linesIntroDuration: 50 readonly property int introDurationLong: 250 readonly property real startOp: 0.0 readonly property int startWidth: 0 readonly property real startTopMargin: height / 2 - heartRate.height / 2 SequentialAnimation { id: intro NumberAnimation { target: heartRate; property: "margin"; to: 25; easing.type: Easing.InOutCubic; duration: introDurationLong } NumberAnimation { target: horizontalLines; property: "stOpacity"; to: 0.3; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: horizontalLines; property: "ndOpacity"; to: 0.5; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: horizontalLines; property: "rdOpacity"; to: 0.6; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: horizontalLines; property: "foOpacity"; to: 0.6; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: horizontalLines; property: "fvOpacity"; to: 0.6; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: verticalLines; property: "stOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: verticalLines; property: "ndOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: verticalLines; property: "rdOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: verticalLines; property: "foOpacity"; to: 1.0; easing.type: Easing.OutCubic; duration: linesIntroDuration } NumberAnimation { target: graphMask; property: "width"; to: graph.width; duration: 2*introDuration } ParallelAnimation { NumberAnimation { target: graphPoint; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration } NumberAnimation { target: minHeader; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration } } NumberAnimation { target: maxHeader; property: "opacity"; to: 1.0; easing.type: Easing.OutCubic; duration: introDuration } } SequentialAnimation { id: heartbeat loops: 2 ParallelAnimation { NumberAnimation { target: heartImg; property: "height"; to: heartImgHeight * 1.2; easing.type: Easing.InCubic; duration: heartbeatDuration } NumberAnimation { target: heartImg; property: "width"; to: heartImgWidth * 1.2; easing.type: Easing.InCubic; duration: heartbeatDuration } } ParallelAnimation { NumberAnimation { target: heartImg; property: "height"; to: heartImgHeight; easing.type: Easing.InCubic; duration: heartbeatDuration } NumberAnimation { target: heartImg; property: "width"; to: heartImgWidth; easing.type: Easing.InCubic; duration: heartbeatDuration } } } Image { id: heartImg anchors.right: heartRate.left anchors.rightMargin: 15 anchors.verticalCenter: heartRate.verticalCenter source: "images/health/heart.png" Behavior on width { NumberAnimation { duration: 300 easing.type: Easing.OutCubic; } } Behavior on height { NumberAnimation { duration: 300 easing.type: Easing.OutCubic; } } } Text { anchors.top: parent.top anchors.topMargin: margin anchors.horizontalCenter: parent.horizontalCenter property int margin: startTopMargin id: heartRate text: HealthModel.HeartRate font.pixelSize: 61 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.whiteColor } Column { id: horizontalLines anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter spacing: 38 property real stOpacity: startOp property real ndOpacity: startOp property real rdOpacity: startOp property real foOpacity: startOp property real fvOpacity: startOp Repeater { model: [ { value: "200" }, { value: "150" }, { value: "100" }, { value: "50" }, { value: "" } ] delegate: Item { opacity: getHorizontalStripeOp(index) Image { id: horizontalImg source: "images/health/horizontal-line.png" } Text { anchors.left: horizontalImg.right anchors.leftMargin: 10 anchors.verticalCenter: horizontalImg.verticalCenter text: modelData.value font.pixelSize: 17 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.grayColor } } } } Row { id: verticalLines anchors.left: parent.left anchors.leftMargin: 60 anchors.bottom: horizontalLines.bottom spacing: 70 property real stOpacity: startOp property real ndOpacity: startOp property real rdOpacity: startOp property real foOpacity: startOp Repeater { model: [ { hour: "10:00" }, { hour: "12:00" }, { hour: "14:00" }, { hour: "16:00" } ] delegate: Item { width: verticalImg.width height: verticalImg.height opacity: getVerticalStripeOp(index) Image { anchors.centerIn: parent id: verticalImg source: "images/health/vertical-line.png" } Text { anchors.top: verticalImg.bottom anchors.topMargin: 10 anchors.horizontalCenter: verticalImg.horizontalCenter text: modelData.hour font.pixelSize: 14 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.grayColor } } } } /* * Graph images */ Item { id: graphMask width:startWidth height:graph.height clip: true anchors.bottom: horizontalLines.bottom anchors.left: horizontalLines.left Image { id: graph source: "images/health/graph.png" } } Image { id: graphPoint source: "images/health/graph-point.png" anchors.bottom: graphMask.bottom anchors.bottomMargin: 50 anchors.right: graphMask.right anchors.rightMargin: 7 opacity: startOp } /* * Minimal heart rate container */ StaticText { anchors.top: horizontalLines.bottom anchors.topMargin: 40 anchors.left: parent.left anchors.leftMargin: 120 opacity: startOp id: minHeader text: "MIN" font.pixelSize: 14 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.grayColor } Text { anchors.top: minHeader.bottom anchors.horizontalCenter: minHeader.horizontalCenter opacity: minHeader.opacity text: HealthModel.MinHeartRate font.pixelSize: 30 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.whiteColor } /* * Maximal heart rate container */ StaticText { anchors.top: horizontalLines.bottom anchors.topMargin: 40 anchors.right: parent.right anchors.rightMargin: 120 opacity: startOp id: maxHeader text: "MAX" font.pixelSize: 14 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.grayColor } Text { anchors.top: maxHeader.bottom anchors.horizontalCenter: maxHeader.horizontalCenter opacity: maxHeader.opacity text: HealthModel.MaxHeartRate font.pixelSize: 30 font.family: Theme.fontFamily font.weight: Font.Medium color: Theme.whiteColor } Timer { id: degreeTimer interval: 1000 running: true repeat: true onTriggered: { HealthModel.update() heartbeat.start() } } onOnScreenChanged: { if (onScreen) { intro.start() } } onOffScreenChanged: { if (offScreen) { resetIntro() } } function resetIntro() { intro.stop() heartRate.margin = startTopMargin horizontalLines.stOpacity = startOp horizontalLines.ndOpacity = startOp horizontalLines.rdOpacity = startOp horizontalLines.foOpacity = startOp horizontalLines.fvOpacity = startOp verticalLines.stOpacity = startOp verticalLines.ndOpacity = startOp verticalLines.rdOpacity = startOp verticalLines.foOpacity = startOp graphMask.width = startWidth graphPoint.opacity = startOp minHeader.opacity = startOp maxHeader.opacity = startOp } function getHorizontalStripeOp(index : int) : real { switch(index) { case 0: return horizontalLines.stOpacity case 1: return horizontalLines.ndOpacity case 2: return horizontalLines.rdOpacity case 3: return horizontalLines.foOpacity case 4: return horizontalLines.fvOpacity } } function getVerticalStripeOp(index : int) : real { switch(index) { case 0: return verticalLines.stOpacity case 1: return verticalLines.ndOpacity case 2: return verticalLines.rdOpacity case 3: return verticalLines.foOpacity } } }