C
Qt Quick Ultralite Watch Demo
/****************************************************************************** ** ** 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 Watch 1.0 Rectangle { id: root height: Theme.appHeight width: Theme.appWidth color: Theme.backgroundColor readonly property real startOpacity: 0.0 readonly property int introAnimationDuration: 100 readonly property int degreeBaseDuration: 3000 readonly property int degreeUpdateInterval: 4000 readonly property int offset: 180 readonly property int directionsCount: 4 readonly property int arrowsCount: 2 readonly property int minDegree: 1 readonly property int maxDegree: 360 readonly property real radianRatio: 0.0174532925 property int currentDegree: 360 onVisibleChanged: { introAnimation.running = visible if (!visible) { resetOpacity() degreeTimer.running = false } } Behavior on currentDegree { NumberAnimation { id: degreeAnimation easing.type: Easing.InOutCubic; } } SequentialAnimation { id: introAnimation running: root.visible NumberAnimation { target: outerRing; property: "opacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: innerRing; property: "opacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: centerRing; property: "opacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: degreeText; property: "opacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: arrows; property: "opacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: directions; property: "nOpacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: directions; property: "eOpacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: directions; property: "sOpacity"; to: 1.0; duration: introAnimationDuration } NumberAnimation { target: directions; property: "wOpacity"; to: 1.0; duration: introAnimationDuration } ScriptAction { script: { updateAngle() degreeTimer.running = true } } } Timer { id: degreeTimer interval: degreeUpdateInterval running: false repeat: true onTriggered: updateAngle() } MouseArea { anchors.fill: parent onClicked: MainModel.compassOn = false } Image { id: centerRing anchors.centerIn: parent source: "images/compass/middleback.png" opacity: startOpacity } Image { id: innerRing anchors.centerIn: parent source: "images/compass/ring1.png" opacity: startOpacity } Image { id: outerRing anchors.centerIn: parent source: "images/compass/ring2.png" opacity: startOpacity } Item { anchors.centerIn: parent id: directions property real nOpacity: startOpacity property real sOpacity: startOpacity property real wOpacity: startOpacity property real eOpacity: startOpacity Repeater { model: ListModel { ListElement { image: "images/compass/N.png" } ListElement { image: "images/compass/W.png" } ListElement { image: "images/compass/S.png" } ListElement { image: "images/compass/E.png" } } delegate: Image { source: model.image opacity: getOpacity(index) property real angle: ((360 / directionsCount) * index + offset - currentDegree) * radianRatio property real radius: root.height / 2 - height / 2 x: radius * Math.sin(angle) - width / 2 y: radius * Math.cos(angle) - height / 2 } } } Image { id: arrows anchors.centerIn: parent source: "images/compass/arrows.png" opacity: startOpacity transform: Rotation { angle: currentDegree origin.x: arrows.width / 2 origin.y: arrows.height / 2 } } Text { anchors.centerIn: parent id: degreeText text: currentDegree font.pixelSize: 86 font.family: Theme.fontFamily color: Theme.whiteColor opacity: startOpacity } function resetOpacity() { arrows.opacity = startOpacity outerRing.opacity = startOpacity innerRing.opacity = startOpacity degreeText.opacity = startOpacity centerRing.opacity = startOpacity degreeText.opacity = startOpacity directions.nOpacity = startOpacity directions.eOpacity = startOpacity directions.sOpacity = startOpacity directions.wOpacity = startOpacity } function getAnimationDuration(oldValue : int, newValue : int) : int { var delta = oldValue - newValue return Math.abs(delta) / 100 * degreeBaseDuration } function getOpacity(index : int) : real { switch(index) { case 0: return directions.nOpacity case 1: return directions.wOpacity case 2: return directions.sOpacity case 3: return directions.eOpacity } } function updateAngle() { var newDegree = currentDegree - 180 if (newDegree < 0) { newDegree = 360 } degreeAnimation.duration = getAnimationDuration(currentDegree, newDegree) currentDegree = newDegree } }