← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~fboucault/ubuntu-clock-app/fix_startup_animation_and_performance into lp:ubuntu-clock-app

 

Florian Boucault has proposed merging lp:~fboucault/ubuntu-clock-app/fix_startup_animation_and_performance into lp:ubuntu-clock-app.

Commit message:
Startup animation and performance fixes:
- Synchronise all elements animated at startup so that they stop moving synchronously
- Added easing to startup animation with UbuntuNumberAnimation
- Use PauseAnimation instead of a Timer
- Move bottom part of the UI away from the clock during intro as per design specification
- Replaced use of resource intensive QtGraphicalEffects with a custom drawn Circle using GLSL (saves GPU and memory)
- Make use of Ubuntu UI Toolkit's scaling feature for Inner_Clock_Texture.png (scales better and saves memory)


Requested reviews:
  Bartosz Kosiorek (gang65)

For more details, see:
https://code.launchpad.net/~fboucault/ubuntu-clock-app/fix_startup_animation_and_performance/+merge/282839
-- 
Your team Ubuntu Clock Developers is subscribed to branch lp:ubuntu-clock-app.
=== modified file 'app/clock/ClockPage.qml'
--- app/clock/ClockPage.qml	2015-10-22 16:49:23 +0000
+++ app/clock/ClockPage.qml	2016-01-16 08:22:29 +0000
@@ -283,7 +283,7 @@
     ParallelAnimation {
         id: otherElementsStartUpAnimation
 
-        PropertyAnimation {
+        UbuntuNumberAnimation {
             target: headerRow
             property: "anchors.topMargin"
             from: units.gu(4)
@@ -291,7 +291,7 @@
             duration: 900
         }
 
-        PropertyAnimation {
+        UbuntuNumberAnimation {
             target: headerRow
             property: "opacity"
             from: 0
@@ -299,7 +299,7 @@
             duration: 900
         }
 
-        PropertyAnimation {
+        UbuntuNumberAnimation {
             target: date
             property: "opacity"
             from: 0
@@ -307,10 +307,10 @@
             duration: 900
         }
 
-        PropertyAnimation {
+        UbuntuNumberAnimation {
             target: date
             property: "anchors.topMargin"
-            from: units.gu(41)
+            from: units.gu(29)
             to: units.gu(37)
             duration: 900
         }

=== modified file 'app/clock/MainClock.qml'
--- app/clock/MainClock.qml	2015-10-22 16:49:23 +0000
+++ app/clock/MainClock.qml	2016-01-16 08:22:29 +0000
@@ -73,7 +73,7 @@
         }
 
         ParallelAnimation {
-            PropertyAnimation {
+            UbuntuNumberAnimation {
                 target: mainClock
                 property: "width"
                 to: units.gu(32)

=== modified file 'app/components/AnalogMode.qml'
--- app/components/AnalogMode.qml	2015-10-22 16:49:23 +0000
+++ app/components/AnalogMode.qml	2016-01-16 08:22:29 +0000
@@ -31,18 +31,11 @@
     signal animationComplete()
 
     function startAnimation() {
-        _animationTimer.start()
+        _innerCircleAnimation.start()
     }
 
     width: units.gu(0)
 
-    Timer {
-        id: _animationTimer
-        interval: 200
-        repeat: false
-        onTriggered: _innerCircleAnimation.start()
-    }
-
     Image {
         id: hourHand
 
@@ -109,12 +102,16 @@
     SequentialAnimation {
         id: _innerCircleAnimation
 
-        PropertyAnimation {
+        PauseAnimation {
+            duration: 200
+        }
+
+        UbuntuNumberAnimation {
             target: _innerCircleAnalog
             property: "width"
             from: units.gu(0)
             to: maxWidth
-            duration: 900
+            duration: 700
         }
 
         // Fire signal that the animation is complete.

=== added file 'app/components/Circle.qml'
--- app/components/Circle.qml	1970-01-01 00:00:00 +0000
+++ app/components/Circle.qml	2016-01-16 08:22:29 +0000
@@ -0,0 +1,48 @@
+import QtQuick 2.4
+
+ShaderEffect {
+    property color color: "#4DFFFFFF"
+    property real borderWidth: 10
+    property color borderColorTop: "#6E6E6E"
+    property color borderColorBottom: "#00000000"
+    property real borderOpacity: 1.0
+    property real borderGradientPosition: 0.5
+
+    property real _texturePixel: 1/width
+    property real _borderWidthTex: borderWidth/width
+    property real _gradientEdge1: borderGradientPosition <= 0.5 ? borderGradientPosition : 0.0
+    property real _gradientEdge2: borderGradientPosition <= 0.5 ? 1.0 : borderGradientPosition
+
+    height: width
+
+    fragmentShader: "
+        varying mediump vec2 qt_TexCoord0;
+        uniform lowp float qt_Opacity;
+        uniform lowp vec4 color;
+        uniform lowp vec4 borderColorTop;
+        uniform lowp vec4 borderColorBottom;
+        uniform lowp float borderOpacity;
+        uniform lowp float borderGradientPosition;
+        uniform lowp float _gradientEdge1;
+        uniform lowp float _gradientEdge2;
+        uniform lowp float _texturePixel;
+        uniform lowp float _borderWidthTex;
+
+        void main() {
+            mediump float radius = 0.5;
+            mediump float radiusBorder = radius-_borderWidthTex;
+            mediump vec2 center = vec2(radius);
+
+            mediump float circleX = (qt_TexCoord0.x - center.x);
+            mediump float circleY = (qt_TexCoord0.y - center.y);
+
+            mediump float edge = circleX*circleX + circleY*circleY;
+            lowp vec4 borderColor = mix(borderColorTop, borderColorBottom, smoothstep(_gradientEdge1, _gradientEdge2, qt_TexCoord0.y)) * borderOpacity;
+            lowp vec4 fillColor = mix(vec4(0),
+                                      mix(borderColor, color, smoothstep(edge-_texturePixel, edge+_texturePixel, radiusBorder*radiusBorder)),
+                                      smoothstep(edge-_texturePixel, edge+_texturePixel, radius*radius));
+            gl_FragColor = fillColor * qt_Opacity;
+        }
+    "
+}
+

=== modified file 'app/components/ClockCircle.qml'
--- app/components/ClockCircle.qml	2015-10-22 16:49:23 +0000
+++ app/components/ClockCircle.qml	2016-01-16 08:22:29 +0000
@@ -34,7 +34,7 @@
   The circle position is set by the public property "isOuter". If true, the
   outer circle characteristics are set and vice-versa.
  */
-Rectangle {
+Circle {
     id: _innerCircle
 
     /*
@@ -42,83 +42,21 @@
      */
     property bool isOuter: false
 
-    height: width
-    radius: width / 2
-    antialiasing: true
-    color: isOuter ? Qt.rgba(1,1,1,0.3) : Qt.rgba(0,0,0,0.03)
-
-    /*
-      Rectangle with a gradient background which will be used as a source for
-      the opacity mask. It starts of transparent and then gradually turns
-      gray at the bottom.
-     */
-    Rectangle {
-        id: _source
-
-        radius: width / 2
-        anchors.fill: parent
-
-        antialiasing: true
-
-        gradient: Gradient {
-            GradientStop {
-                position: 0.0
-                color: isOuter ? "#6E6E6E" : "Transparent"
-            }
-
-            GradientStop {
-                position: isOuter ? 0.7 : 0.3
-                color: "Transparent"
-            }
-
-            GradientStop {
-                position: 1.0
-                color: isOuter ? "Transparent" : "#6E6E6E"
-            }
-        }
-    }
-
-    Loader {
-        id: _innerBackgroundLoader
-        anchors.fill: parent
-        sourceComponent: !isOuter ? _innerBackground : undefined
-    }
-
-    Component {
-        id: _innerBackground
-        Image {
-            smooth: false
-            fillMode: Image.PreserveAspectFit
-            source: "../graphics/Inner_Clock_Texture.png"
-        }
-    }
-
-    /*
-      Rectangle which will be masked over by the source rectangle. This
-      rectangle is required for the border effect which results in the
-      shadow.
-     */
-    Rectangle {
-        id: _mask
-
-        radius: (width / 2)
-        anchors.fill: _source
-
-        antialiasing: true
-        color: "Transparent"
-        border { width: units.gu(0.2) }
-    }
-    
-    OpacityMask {
-        opacity: 0.65
-        anchors.fill: _source
-        source: ShaderEffectSource {
-            sourceItem: _source
-            hideSource: true
-        }
-        maskSource: ShaderEffectSource {
-            sourceItem: _mask
-            hideSource: true
-        }
+    color: isOuter ? "#4DFFFFFF" : "#08000000"
+    borderWidth: units.gu(0.2)
+    borderColorTop: isOuter ? "#6E6E6E" : "#00000000"
+    borderColorBottom: isOuter ? "#00000000" : "#6E6E6E"
+    borderOpacity: 0.65
+    borderGradientPosition: isOuter ? 0.7 : 0.2
+
+    Image {
+        anchors.fill: parent
+        anchors.margins: borderWidth / 2.0
+        smooth: true
+        fillMode: Image.PreserveAspectFit
+        source: !isOuter ? "../graphics/Inner_Clock_Texture.png" : ""
+        sourceSize.width: width
+        sourceSize.height: height
+        cache: false
     }
 }

=== modified file 'app/components/DigitalMode.qml'
--- app/components/DigitalMode.qml	2015-10-22 16:49:23 +0000
+++ app/components/DigitalMode.qml	2016-01-16 08:22:29 +0000
@@ -36,17 +36,11 @@
     signal animationComplete()
 
     function startAnimation() {
-        _animationTimer.start()
-    }
-
-    width: units.gu(0)
-
-    Timer {
-        id: _animationTimer
-        interval: 200
-        repeat: false
-        onTriggered: _innerCircleAnimation.start()
-    }
+        scale = 0
+        _innerCircleAnimation.start()
+    }
+
+    width: maxWidth
 
     Label {
         id: _digitalTime
@@ -54,7 +48,7 @@
         anchors.centerIn: parent
 
         color: UbuntuColors.midAubergine
-        font.pixelSize: units.dp(1)
+        font.pixelSize: maxTimeFontSize
         text: {
             if (localizedTimeString.search(Qt.locale().amText) !== -1) {
                 // 12 hour format detected with the localised AM text
@@ -78,7 +72,7 @@
         anchors.horizontalCenter: parent.horizontalCenter
 
         color: UbuntuColors.midAubergine
-        font.pixelSize: units.dp(1)
+        font.pixelSize: maxPeriodFontSize
         visible: text !== ""
         text: {
             if (localizedTimeString.search(Qt.locale().amText) !== -1) {
@@ -99,30 +93,16 @@
     SequentialAnimation {
         id: _innerCircleAnimation
 
-        ParallelAnimation {
-            PropertyAnimation {
-                target: _innerCircle
-                property: "width"
-                from: units.gu(0)
-                to: maxWidth
-                duration: 900
-            }
-
-            PropertyAnimation {
-                target: _digitalTime
-                property: "font.pixelSize"
-                from: units.dp(1)
-                to: maxTimeFontSize
-                duration: 900
-            }
-
-            PropertyAnimation {
-                target: _digitalTimePeriod
-                property: "font.pixelSize"
-                from: units.dp(1)
-                to: maxPeriodFontSize
-                duration: 900
-            }
+        PauseAnimation {
+            duration: 200
+        }
+
+        UbuntuNumberAnimation {
+            target: _innerCircle
+            property: "scale"
+            from: 0
+            to: 1
+            duration: 700
         }
 
         // Fire signal that the animation is complete.

=== renamed file 'app/graphics/Inner_Clock_Texture.png' => 'app/graphics/Inner_Clock_Texture@xxxxxx'

Follow ups