C
Qt Quick Ultralite Motorcycle Cluster Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
import QtQuick 2.4
import QtQuickUltralite.Extras 2.0
Item {
id: root
width: 228
height: 228
property bool active
property bool isDayMode
property real fuelLevel: 30
property real fuelLevelForStartupAnimation: 0
property real fuelLevelVisibleValue: (startUpAnimation.running
|| hideAnimation.running
|| dayModeAnimation.running
|| nightModeAnimation.running) ? fuelLevelForStartupAnimation : fuelLevel
property color colorMode: fuelLevel < 20 ? Style.red : (fuelLevel < 40 ? Style.orange : Style.neutralGreen)
property color imagesColors
property image holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg.png"
property real gradientCircleOpacityTarget: 1
property real backgroundOpacityTarget: 1
states: [
State {
name: "dayMode"
when: isDayMode === true
PropertyChanges {
target: root
imagesColors: Style.black
}
PropertyChanges {
target: root
holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg-day.png"
}
PropertyChanges {
target: background
opacity: 0
}
PropertyChanges {
target: root
gradientCircleOpacityTarget: 0
}
PropertyChanges {
target: gradientCircle
opacity: 0
}
PropertyChanges {
target: root
backgroundOpacityTarget: 0
}
PropertyChanges {
target: holeInBackground
opacity: 1
}
},
State {
name: "nightMode"
when: isDayMode !== true
PropertyChanges {
target: root
imagesColors: Style.white
}
PropertyChanges {
target: root
holeInBackgroundImg: "qrc:///images/fuelGauge/hole-in-bg.png"
}
PropertyChanges {
target: background
opacity: 1
}
PropertyChanges {
target: root
gradientCircleOpacityTarget: 1
}
PropertyChanges {
target: gradientCircle
opacity: 1
}
PropertyChanges {
target: root
backgroundOpacityTarget: 1
}
}
]
transitions: [
Transition {
to: "dayMode"
SequentialAnimation {
id: dayModeAnimation
ParallelAnimation {
ScriptAction {
script: {
fuelLevelForStartupAnimation = 0
}
}
NumberAnimation {
target: background
duration: 300
property: "opacity"
to: 0
easing.type: Easing.OutCubic
}
NumberAnimation {
target: gradientCircle
duration: 300
property: "opacity"
to: 0
easing.type: Easing.OutCubic
}
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 0
duration: 300
easing.type: Easing.OutCubic
}
ScriptAction {
script: {
holeInBackground.source = holeInBackgroundImg
}
}
PauseAnimation {
duration: 1000
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 1
duration: 300
easing.type: Easing.OutCubic
}
ScriptAction {
script: {
fuelLevelForStartupAnimation = fuelLevel
}
}
PauseAnimation {
duration: 300
}
}
},
Transition {
to: "nightMode"
SequentialAnimation {
id: nightModeAnimation
ScriptAction {
script: {
fuelLevelForStartupAnimation = 0
}
}
PauseAnimation {
duration: 300
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 0
duration: 300
easing.type: Easing.OutCubic
}
ScriptAction {
script: {
holeInBackground.source = holeInBackgroundImg
}
}
PauseAnimation {
duration: 1000
}
NumberAnimation {
target: holeInBackground
property: "opacity"
to: 1
duration: 300
easing.type: Easing.OutCubic
}
ParallelAnimation {
ScriptAction {
script: {
fuelLevelForStartupAnimation = fuelLevel
}
}
NumberAnimation {
target: gradientCircle
duration: 300
easing.type: Easing.OutCubic
}
NumberAnimation {
target: background
duration: 300
property: "opacity"
to: 0
easing.type: Easing.OutCubic
}
}
}
}
]
Behavior on fuelLevelForStartupAnimation {
NumberAnimation {
duration: 800
easing.type: Easing.OutCubic
}
}
Image {
id: background
source: "qrc:///images/fuelGauge/fuel-colored-bg.png"
anchors.centerIn: root
}
Item {
id: hole
width: 171
height: 171
anchors.centerIn: root
clip: true
property int wavesOffset: 0
ColorizedImage {
id: fuelLevelImage
source: "qrc:///images/fuelGauge/wave-bottom-part.png"
color: root.colorMode
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: MathAPI.clamp(
root.fuelLevelVisibleValue / 80 * 135 - 135,
-135, 0)
}
ColorizedImage {
id: wave
source: "qrc:///images/fuelGauge/wave-top-part.png"
color: root.colorMode
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: hole.wavesOffset
anchors.bottom: fuelLevelImage.top
}
ColorizedImage {
id: wave_2
source: "qrc:///images/fuelGauge/wave-top-part.png"
color: root.colorMode
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -60 - hole.wavesOffset
anchors.bottom: fuelLevelImage.top
}
Image {
id: wave_2_shadow
source: "qrc:///images/fuelGauge/wave-shadow.png"
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -60 - hole.wavesOffset
anchors.bottom: fuelLevelImage.top
}
Image {
id: holeInBackground
anchors.centerIn: parent
source: "qrc:///images/fuelGauge/hole-in-bg.png"
}
SequentialAnimation {
id: wavesAnimation
running: true
loops: Animation.Infinite
NumberAnimation {
target: hole
property: "wavesOffset"
duration: 5000
from: -90
to: 90
}
NumberAnimation {
target: hole
property: "wavesOffset"
duration: 5000
from: 90
to: -90
}
}
}
ColorizedImage {
id: gradientCircle
color: root.colorMode
anchors.centerIn: root
source: "qrc:///images/fuelGauge/fuel-colored-circle.png"
}
ColorizedImage {
id: fuelScale
source: "qrc:///images/fuelGauge/fuel-scale.png"
anchors.centerIn: root
color: imagesColors
anchors.horizontalCenterOffset: 15
}
ColorizedImage {
id: ring1
source: "qrc:///images/fuelGauge/ring-2.png"
anchors.centerIn: root
width: 195
height: 195
color: imagesColors
}
ColorizedImage {
id: ring2
source: "qrc:///images/fuelGauge/ring-2.png"
anchors.centerIn: root
property int horizontalCenterOffsetValue
anchors.horizontalCenterOffset: horizontalCenterOffsetValue
color: imagesColors
}
function hideElements() {
ring1.opacity = 0
ring2.opacity = 0
hole.opacity = 0
fuelLevelForStartupAnimation = 0
fuelScale.opacity = 0
background.opacity = 0
gradientCircle.opacity = 0
}
onActiveChanged: {
if (active) {
startAnimation()
} else {
hiddingAnimation()
}
}
function startAnimation() {
startUpAnimation.start()
}
function hiddingAnimation() {
hideAnimation.start()
}
SequentialAnimation {
id: hideAnimation
ScriptAction {
script: {
root.fuelLevelForStartupAnimation = 0
}
}
PauseAnimation {
duration: 500
}
ScriptAction {
script: {
hole.opacity = 0
}
}
NumberAnimation {
target: root
property: "opacity"
to: 0
duration: 500
easing.type: Easing.OutCubic
}
ScriptAction {
script: hideElements()
}
}
SequentialAnimation {
id: startUpAnimation
ScriptAction {
script: {
hideElements()
root.opacity = 1
}
}
ParallelAnimation {
NumberAnimation {
target: ring2
property: "horizontalCenterOffsetValue"
from: StartupConfig.ring2TravelDistance
to: 0
duration: StartupConfig.ring2TravelDuration
easing.type: Easing.OutCubic
}
NumberAnimation {
target: ring2
property: "opacity"
from: 0
to: 1
duration: StartupConfig.ring2OpacityDuration
easing.type: Easing.OutCubic
}
}
ParallelAnimation {
ScriptAction {
script: {
hole.opacity = 1
}
}
SequentialAnimation {
PauseAnimation {
duration: 300
}
ScriptAction {
script: {
root.fuelLevelForStartupAnimation = 45
}
}
PauseAnimation {
duration: 600
}
ScriptAction {
script: {
root.fuelLevelForStartupAnimation = 30
}
}
PauseAnimation {
duration: 600
}
ScriptAction {
script: {
root.fuelLevelForStartupAnimation = root.fuelLevel
}
}
PauseAnimation {
duration: 600
}
}
SequentialAnimation {
NumberAnimation {
target: ring1
property: "opacity"
from: 0
to: 1
duration: 300
easing.type: Easing.OutQuad
}
NumberAnimation {
target: gradientCircle
property: "opacity"
to: gradientCircleOpacityTarget
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutQuad
}
ParallelAnimation {
NumberAnimation {
target: fuelScale
property: "opacity"
to: 1
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutQuad
}
NumberAnimation {
target: background
property: "opacity"
to: backgroundOpacityTarget
duration: StartupConfig.backgroundOpacityDuration
easing.type: Easing.OutQuad
}
}
}
}
}
Component.onCompleted: {
hideElements()
}
}