on 68669d9 help sign in
unity8/Components/CrossFadeImage.qml
149 lines 4.1 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17import QtQuick 2.0
19Item {
20 property url source
22 /*
23 * true: fade out old image in parallel with fading in the new one.
24 * false: fade in new image above old one.
25 *
26 * The reason why this is required is that crossfading has the isse that in
27 * the middle of the animation, both images are only 50% opaque which make
28 * any background shine through. Not wanted for background images etc, but
29 * wanted for overlays.
30 */
31 property bool crossFade: true
33 /*
34 * true: the very first source url should be faded in already.
35 * false: the very first source url should just be shown without animation.
36 */
37 property bool fadeInFirst: true
39 readonly property size sourceSize: __currentImage.sourceSize
40 readonly property var status: __currentImage ? __currentImage.status : Image.Null
41 readonly property bool running: crossFadeImages.running || nextImageFadeIn.running
43 property Image __currentImage: image1
44 property Image __nextImage: image2
46 function swapImages() {
47 __currentImage.z = 0
48 __nextImage.z = 1
49 if (crossFade) {
50 crossFadeImages.start();
51 } else {
52 nextImageFadeIn.start();
53 }
55 var tmpImage = __currentImage
56 __currentImage = __nextImage
57 __nextImage = tmpImage
58 }
60 onSourceChanged: {
61 // On creation, the souce handler is called before image pointers are set.
62 if (__currentImage === null) {
63 __currentImage = image1;
64 __nextImage = image2;
65 }
67 crossFadeImages.stop();
68 nextImageFadeIn.stop();
70 // Don't fade in initial picture, only fade changes
71 if (__currentImage.source == "" && !fadeInFirst) {
72 __currentImage.source = source;
73 } else {
74 nextImageFadeIn.stop();
75 __nextImage.opacity = 0.0;
76 __nextImage.source = source;
78 // If case the image is still in QML's cache, status will be "Ready" immediately
79 if (__nextImage.status == Image.Ready || __nextImage.source == "") {
80 swapImages();
81 }
82 }
83 }
85 Connections {
86 target: __nextImage
87 onStatusChanged: {
88 if (__nextImage.status == Image.Ready) {
89 swapImages();
90 }
91 }
92 }
94 Image {
95 id: image1
96 anchors.fill: parent
97 cache: false
98 asynchronous: true
99 z: 1
100 }
102 Image {
103 id: image2
104 anchors.fill: parent
105 cache: false
106 asynchronous: true
107 z: 0
108 }
110 NumberAnimation {
111 id: nextImageFadeIn
112 target: __nextImage
113 property: "opacity"
114 duration: 400
115 to: 1.0
116 easing.type: Easing.InOutQuad
118 onRunningChanged: {
119 if (!running) {
120 __nextImage.source = "";
121 }
122 }
123 }
125 ParallelAnimation {
126 id: crossFadeImages
127 NumberAnimation {
128 target: __nextImage
129 property: "opacity"
130 duration: 400
131 to: 1.0
132 easing.type: Easing.InOutQuad
133 }
135 NumberAnimation {
136 target: __currentImage
137 property: "opacity"
138 duration: 400
139 to: 0
140 easing.type: Easing.InOutQuad
141 }
143 onRunningChanged: {
144 if (!running) {
145 __nextImage.source = "";
146 }
147 }
148 }