[gnome-shell/wip/fmuellner/ease-actors: 19/20] environment: Add convenience method for implicit animations



commit 298f6857b9cc9ff6528692f3f90750903615e07a
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Jun 10 02:52:12 2017 +0200

    environment: Add convenience method for implicit animations
    
    Setting up implicit animations is more verbose than using tweener, in
    particular when setting up a callbacks to run on overwrite or completion.
    In order to make its use more convenient, monkey-patch ClutterActor
    with an ease() method that works similarly to Tweener.addTween().
    
    https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/22

 js/ui/environment.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
---
diff --git a/js/ui/environment.js b/js/ui/environment.js
index a1ffd60e5..d36521736 100644
--- a/js/ui/environment.js
+++ b/js/ui/environment.js
@@ -58,6 +58,73 @@ function _patchLayoutClass(layoutClass, styleProps) {
     };
 }
 
+let _easingTransitions = new Map();
+
+function _trackTransition(transition, callback) {
+    if (_easingTransitions.has(transition))
+        transition.disconnect(_easingTransitions.get(transition));
+
+    let id = transition.connect('stopped', isFinished => {
+        _easingTransitions.delete(transition);
+        callback(isFinished);
+    });
+
+    _easingTransitions.set(transition, id);
+}
+
+function _makeEaseCallback(params) {
+    let onComplete = params.onComplete;
+    delete params.onComplete;
+
+    let onStopped = params.onStopped;
+    delete params.onStopped;
+
+    if (!onComplete && !onStopped)
+        return null;
+
+    return isFinished => {
+        if (onStopped)
+            onStopped(isFinished);
+        if (onComplete && isFinished)
+            onComplete();
+    };
+}
+
+function _easeActor(actor, params) {
+    actor.save_easing_state();
+
+    if (params.duration != undefined)
+        actor.set_easing_duration(params.duration);
+    delete params.duration;
+
+    if (params.delay != undefined)
+        actor.set_easing_delay(params.delay);
+    delete params.delay;
+
+    if (params.mode != undefined)
+        actor.set_easing_mode(params.mode);
+    delete params.mode;
+
+    let callback = _makeEaseCallback(params);
+
+    // cancel overwritten transitions
+    let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
+    animatedProps.forEach(p => actor.remove_transition(p));
+
+    actor.set(params);
+
+    if (callback) {
+        let transition = actor.get_transition(animatedProps[0]);
+
+        if (transition)
+            _trackTransition(transition, callback);
+        else
+            callback(true);
+    }
+
+    actor.restore_easing_state();
+}
+
 function _loggingFunc(...args) {
     let fields = { 'MESSAGE': args.join(', ') };
     let domain = "GNOME Shell";
@@ -103,6 +170,10 @@ function init() {
         origSetEasingDelay.call(this, adjustAnimationTime(msecs));
     };
 
+    Clutter.Actor.prototype.ease = function(props, easingParams) {
+        _easeActor(this, props, easingParams);
+    };
+
     Clutter.Actor.prototype.toString = function() {
         return St.describe_actor(this);
     };


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]