on xenial help sign in
reworked animation
commit240add3ec8e3c613a12e2ec8bb508e50588b3a77 authorMichael Zanetti <michael.zanetti@canonical.com> dateTue 14 Jan 2014, 12:57 (13 years ago) parent8c220a2
1 file changed+156−87
qml/Stages/PhoneStage.qml+156−87
qml/Stages/PhoneStage.qml+156−87
@@ -191,7 +191,7 @@ Item {
191191 priv.requestNewScreenshot();
192192 }
193193 if (dragging && !priv.waitingForScreenshot) {
194− coverFlip.progress = -(touchX - root.dragAreaWidth) / root.width
194+ coverFlickable.contentX = -touchX
195195 }
196196 }
197197
@@ -219,45 +219,23 @@ Item {
219219 anchors.fill: root
220220 blockInput: coverFlip.visible
221221 }
222− MouseArea {
222+ Flickable {
223+ id: coverFlickable
223224 anchors.fill: root
225+ contentHeight: height
226+ contentWidth: width * ApplicationManager.count
227+ flickableDirection: Qt.Horizontal
224228 enabled: coverFlip.visible
225− property int oldMouseX
226− property int startX
227229
228− property bool isDrag: false
229−
230− onPressed: {
231− isDrag = false
232− oldMouseX = mouseX
233− startX = mouseX
234− }
235−
236− onMouseXChanged: {
237− var diff = (oldMouseX - mouseX) * .001;
238− coverFlip.progress = Math.max(.8, coverFlip.progress + diff);
239− oldMouseX = mouseX
240− print("mousex changed", mouseX - startX)
241− if (Math.abs(mouseX - startX) > units.gu(.5)) {
242− isDrag = true;
243− }
244− }
245− onClicked: {
246− // From Qt docs:
247− // "A click is defined as a press followed by a release, both inside the
248− // MouseArea (pressing, moving outside the MouseArea, and then moving back
249− // inside and releasing is also considered a click)."
250− // This means, that pressing, moving the coverFlip around and then releasing
251− // will still be threated as a click. Let's add our own logic to not activate
252− // a tile if the user just wants to drag stuff around.
253− if (isDrag) {
254− return;
230+ onContentXChanged: {
231+// print("contentX changed", contentX)
232+ var progress = contentX / width
233+ if (progress > .5) {
234+ progress += progress - .5
255235 }
256236
257− var index = Math.floor(mouseX / coverFlip.tileWidth)
258− index = Math.min(tileRepeater.count - 1, index)
259− print("clicked item", index)
260− coverFlip.selectItem(index);
237+ coverFlip.progress = progress;
238+// print("progress is", coverFlip.progress)
261239 }
262240 }
263241
@@ -268,22 +246,37 @@ Item {
268246 visible: progress > 0
269247
270248 property real progress: 0
271− property int maxAngle: 45
249+ property real startAngle: 45
250+ property int endAngle: 10
251+
252+ property real maxScale: 1.4
272253 property real minScale: .6
254+
255+ // Markers: relative screen position from left to right
256+ // marks the line where first application is finished moving in from the right
257+ property real progressMarker1: 0.5
258+
273259 property bool animatingBack: false
274260
275− property real tileWidth: Math.max(units.gu(2), root.width - (coverFlip.progress * root.width))
261+ property real tileWidth: root.width
276262
277−// onProgressChanged: print("CoverFlip progress changed", progress)
278− onXChanged: print("coverflip x changed", x)
263+ property real oldProgress: 0
264+ onProgressChanged: {
265+ if (oldProgress <= coverFlip.progressMarker1 && progress > coverFlip.progressMarker1) {
266+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
267+ } else if (oldProgress >= 0.5 && progress < 0.5) {
268+ ApplicationManager.focusApplication(ApplicationManager.get(1).appId)
269+ }
270+ oldProgress = progress;
271+ }
279272
280273 function snap() {
281274 if (coverFlip.progress < 0.25) {
282− snapAnimation.targetProgress = 0
275+ snapAnimation.targetContentX = 0
283276 } else if (coverFlip.progress < 0.6) {
284− snapAnimation.targetProgress = 0.5
277+ snapAnimation.targetContentX = root.width * coverFlip.progressMarker1
285278 } else {
286− snapAnimation.targetProgress = .8;
279+ snapAnimation.targetContentX = root.width * .9;
287280 }
288281 snapAnimation.start();
289282 }
@@ -294,18 +287,17 @@ Item {
294287
295288 SequentialAnimation {
296289 id: snapAnimation
297− property var targetProgress
290+ property var targetContentX
298291
299292 UbuntuNumberAnimation {
300− target: coverFlip
301− properties: "progress"
302− to: snapAnimation.targetProgress
293+ target: coverFlickable
294+ properties: "contentX"
295+ to: snapAnimation.targetContentX
303296 }
304297 ScriptAction {
305298 script: {
306− if (snapAnimation.targetProgress == 0.5) {
307− ApplicationManager.focusApplication(ApplicationManager.get(1).appId);
308− coverFlip.progress = 0;
299+ if (snapAnimation.targetContentX == root.width * coverFlip.progressMarker1) {
300+ coverFlickable.contentX = 0;
309301 }
310302 }
311303 }
@@ -332,80 +324,157 @@ Item {
332324
333325 property real progress: coverFlip.progress
334326
327+ property int xTranslation: {
328+ var xTranslate = 0;
329+ var minXTranslate = -index * root.width + index * units.dp(3);
330+ switch (index) {
331+ case 0:
332+ if (appImage.progress < coverFlip.progressMarker1) {
333+ var progress = appImage.progress
334+ var progressDiff = coverFlip.progressMarker1
335+ var translateDiff = -root.width * 0.25
336+ // progress : progressDiff = translate : translateDiff
337+ xTranslate = progress * translateDiff / progressDiff
338+ }
339+ break;
340+ case 1:
341+ if (appImage.progress < coverFlip.progressMarker1) {
342+ var progress = appImage.progress;
343+ var progressDiff = coverFlip.progressMarker1;
344+ var translateDiff = -root.width;
345+ // progress : progressDiff = translate : translateDiff
346+ xTranslate = progress * translateDiff / progressDiff;
347+ break;
348+ }
349+ // Intentionally no break here...
350+ default:
351+ if (appImage.progress > coverFlip.progressMarker1) {
352+ // Used to move all tiles directly to the right of the screen as starting position
353+ var mainTranslate = -root.width * (index - 1)
354+ // Used to add the offset to each tile so they are not on one stack
355+ var indexTranslate = (index - 1) * root.width / 4
356+
357+ var progress = appImage.progress - coverFlip.progressMarker1
358+ var progressDiff = 1 - coverFlip.progressMarker1
359+ var translateDiff = -root.width * coverFlip.progressMarker1// -(coverFlip.progressMarker1 + index * root.width * 0.25 + root.width * 0.25)
360+
361+ // progress : progressDiff = translate : translateDiff
362+ xTranslate = progress * translateDiff / progressDiff;
363+
364+ // Add starting point and index translate
365+ xTranslate += mainTranslate + indexTranslate;
366+
367+ // make sure we stop at the left screen edge
368+ xTranslate = Math.max(xTranslate, minXTranslate)
369+ break;
370+ }
371+ }
372+ return xTranslate;
373+ }
374+
335375 transform: [
336376 Rotation {
337− origin { x: units.gu(5); y: height / 2 }
377+ origin { x: 0; y: coverFlip.height / 2 }
338378 axis { x: 0; y: 1; z: 0 }
339379 angle: {
340380 var newAngle = 0;
341381 if (coverFlip.animatingBack) {
342− newAngle = Math.min(appImage.progress, .75) * coverFlip.maxAngle;
382+ newAngle = Math.min(appImage.progress, .75) * coverFlip.endAngle;
343383 } else {
344384 switch (index) {
345385 case 0:
346− if (appImage.progress < .5) {
347− newAngle = appImage.progress * coverFlip.maxAngle;
386+ if (appImage.progress <= coverFlip.progressMarker1) {
387+ var progress = appImage.progress;
388+ var angleDiff = coverFlip.endAngle;
389+ var progressDiff = coverFlip.progressMarker1;
390+ // progress : progressDiff = angle : angleDiff
391+ newAngle = progress * angleDiff / progressDiff;
348392 } else {
349− newAngle = (appImage.progress - .5) * coverFlip.maxAngle * 2;
393+ var progress = appImage.progress - coverFlip.progressMarker1;
394+ var angleDiff = coverFlip.endAngle;
395+ var progressDiff = 1 - coverFlip.progressMarker1;
396+ // progress : progressDiff = angle : angleDiff
397+ newAngle = progress * angleDiff / progressDiff;
398+ newAngle = Math.min(coverFlip.endAngle, newAngle);
350399 }
351400 break;
352401 case 1:
353− if (appImage.progress < .5) {
354− newAngle = coverFlip.maxAngle - (appImage.progress * coverFlip.maxAngle * 2);
355− } else {
356− newAngle = (appImage.progress - .5) * coverFlip.maxAngle * 2;
402+ if (appImage.progress < coverFlip.progressMarker1) {
403+ var progress = coverFlip.progress;
404+ var angleDiff = coverFlip.startAngle;
405+ var progressDiff = coverFlip.progressMarker1;
406+ // progress : progressDiff = angle : angleDiff
407+ var angle = progress * angleDiff / progressDiff;
408+ newAngle = coverFlip.startAngle - angle;
409+ break;
357410 }
358− break;
411+ // Intentionally no break here...
359412 default:
360− newAngle = Math.min(appImage.progress, .75) * coverFlip.maxAngle;
413+ var progress = appImage.progress;
414+ var angleDiff = coverFlip.startAngle - coverFlip.endAngle;
415+ var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
416+ // progress : progressDiff = angle : angleDiff
417+ newAngle = progress * angleDiff / progressDiff;
418+ newAngle = Math.max(coverFlip.endAngle, coverFlip.startAngle - newAngle)
361419 }
362420 }
363− return Math.min(newAngle, coverFlip.maxAngle);
421+ return newAngle;
364422 }
365423 },
366424 Translate {
367− x: {
368− if (coverFlip.animatingBack) {
369− return 0;
370− }
371−
372− switch (index) {
373− case 1:
374− if (appImage.progress < .5) {
375− return -root.width * appImage.progress;
376− } else if (appImage.progress < .75) {
377− // relation equation: x : width/2 = progress-.5 : 0.25
378− return (-root.width * .5) + (root.width/2) * (appImage.progress - .5) / 0.25
379− }
380− }
381− return 0;
382− }
425+ x: appImage.xTranslation
383426 },
384427 Scale {
385− origin { x: 0; y: root.height / 2 }
428+ origin { x: appImage.xTranslation; y: root.height / 2 - (root.height - appImage.height)}
386429 xScale: {
387430 var scale = 1;
388− // progress : 1 = x : root.width
389− var progress = root.width / (root.width - x)
390− if (appImage.progress > .5) {
391− // relation equation: scale : (1-minScale) = progress-.5 : 0.5
392− scale = 1 - (1 - coverFlip.minScale) * (appImage.progress - 0.5) / 0.5
431+
432+ switch (index) {
433+ case 0:
434+ if (appImage.progress > coverFlip.progressMarker1) {
435+ var scaleDiff = coverFlip.maxScale - 1;
436+ var progressDiff = 1.5 - coverFlip.progressMarker1;
437+ // progress : progressDiff = scale : scaleDiff
438+ scale = 1 - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff;
439+ }
440+ break;
441+ case 1:
442+ if (appImage.progress < coverFlip.progressMarker1) {
443+ var scaleDiff = coverFlip.maxScale - 1
444+ var progressDiff = coverFlip.progressMarker1
445+ // progress : progressDiff = scale : scaleDiff
446+ scale = coverFlip.maxScale - (appImage.progress * scaleDiff / progressDiff);
447+ break;
448+ }
449+ // Intentionally no break
450+ default:
451+ var scaleDiff = coverFlip.maxScale - coverFlip.minScale
452+ var progressDiff = coverFlip.progressMarker1 + index * 0.25 + 0.25
453+ // progress : progressDiff = scale : scaleDiff
454+ scale = coverFlip.maxScale - (appImage.progress - coverFlip.progressMarker1) * scaleDiff / progressDiff
455+ break;
393456 }
394− scale = Math.max(coverFlip.minScale, scale);
395− return scale;
457+ return Math.min(coverFlip.maxScale, Math.max(coverFlip.minScale, scale));
396458 }
397459 yScale: xScale
398460 }
399461 ]
400462
463+ MouseArea {
464+ anchors.fill: parent
465+ onClicked: {
466+ print("clicked on index", index)
467+ select()
468+ }
469+ }
401470 }
402471
403472 SequentialAnimation {
404473 id: switchToAppAnimation
405474 PropertyAction { target: coverFlip; property: "animatingBack"; value: true }
406475 ParallelAnimation {
407− UbuntuNumberAnimation { target: coverFlip; property: "progress"; to: 0 }
408− UbuntuNumberAnimation { target: coverFlip; property: "x"; to: -root.width * index }
476+ UbuntuNumberAnimation { target: coverFlickable; property: "contentX"; to: 0; duration: 5000 }
477+ UbuntuNumberAnimation { target: coverFlip; property: "x"; to: -root.width * index; duration: 5000 }
409478 }
410479 ScriptAction {
411480 script: {