C
Qt Quick Ultralite Watch Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
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
}
}