[gnome-shell/wip/fmuellner/ease-actors: 4/6] tweener: Use implicit animations for actors if possible
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/fmuellner/ease-actors: 4/6] tweener: Use implicit animations for actors if possible
- Date: Thu, 8 Feb 2018 20:09:04 +0000 (UTC)
commit 4e306c262c4261ae78c4916cfab3d82077425915
Author: Florian Müllner <fmuellner gnome org>
Date: Sat Jun 10 04:14:12 2017 +0200
tweener: Use implicit animations for actors if possible
The Tweener API is used all over the place, so once we port actors to
the new ease() convenience method, making any changes to that API will
become cumbersome. So at least while we are still experimenting, it
makes sense to not change users of Tweener.addTween(), but instead
modify Tweener to use implicit animations internally where possible.
And even if we decide on a proper port in the future, this will still
be useful for making extensions use easing.
js/ui/tweener.js | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 119 insertions(+)
---
diff --git a/js/ui/tweener.js b/js/ui/tweener.js
index 6b1d24c23..30bf359e8 100644
--- a/js/ui/tweener.js
+++ b/js/ui/tweener.js
@@ -29,6 +29,117 @@ function init() {
Tweener.setFrameTicker(new ClutterFrameTicker());
}
+const transitionTranslations = {
+ easeNone: Clutter.AnimationMode.LINEAR,
+ linear: Clutter.AnimationMode.LINEAR,
+ easeInQuad: Clutter.AnimationMode.EASE_IN_QUAD,
+ easeOutQuad: Clutter.AnimationMode.EASE_OUT_QUAD,
+ easeInOutQuad: Clutter.AnimationMode.EASE_IN_OUT_QUAD,
+ easeOutInQuad: undefined,
+ easeInCubic: Clutter.AnimationMode.EASE_IN_CUBIC,
+ easeOutCubic: Clutter.AnimationMode.EASE_OUT_CUBIC,
+ easeInOutCubic: Clutter.AnimationMode.EASE_IN_OUT_CUBIC,
+ easeOutInCubic: undefined,
+ easeInQuart: Clutter.AnimationMode.EASE_IN_QUART,
+ easeOutQuart: Clutter.AnimationMode.EASE_OUT_QUART,
+ easeInOutQuart: Clutter.AnimationMode.EASE_IN_OUT_QUART,
+ easeOutInQuart: undefined,
+ easeInQuint: Clutter.AnimationMode.EASE_IN_QUINT,
+ easeOutQuint: Clutter.AnimationMode.EASE_OUT_QUINT,
+ easeInOutQuint: Clutter.AnimationMode.EASE_IN_OUT_QUINT,
+ easeOutInQuint: undefined,
+ easeInSine: Clutter.AnimationMode.EASE_IN_SINE,
+ easeOutSine: Clutter.AnimationMode.EASE_OUT_SINE,
+ easeInOutSine: Clutter.AnimationMode.EASE_IN_OUT_SINE,
+ easeOutInSine: undefined,
+ easeInExpo: Clutter.AnimationMode.EASE_IN_EXPO,
+ easeOutExpo: Clutter.AnimationMode.EASE_OUT_EXPO,
+ easeInOutExpo: Clutter.AnimationMode.EASE_IN_OUT_EXPO,
+ easeOutInExpo: undefined,
+ easeInCirc: Clutter.AnimationMode.EASE_IN_CIRC,
+ easeOutCirc: Clutter.AnimationMode.EASE_OUT_CIRC,
+ easeInOutCirc: Clutter.AnimationMode.EASE_IN_OUT_CIRC,
+ easeOutInCirc: undefined,
+ easeInElastic: Clutter.AnimationMode.EASE_IN_ELASTIC,
+ easeOutElastic: Clutter.AnimationMode.EASE_OUT_ELASTIC,
+ easeInOutElastic: Clutter.AnimationMode.EASE_IN_OUT_ELASTIC,
+ easeOutInElastic: undefined,
+ easeInBack: Clutter.AnimationMode.EASE_IN_BACK,
+ easeOutBack: Clutter.AnimationMode.EASE_OUT_BACK,
+ easeInOutBack: Clutter.AnimationMode.EASE_IN_OUT_BACK,
+ easeOutInBack: undefined,
+ easeInBounce: Clutter.AnimationMode.EASE_IN_BOUNCE,
+ easeOutBounce: Clutter.AnimationMode.EASE_OUT_BOUNCE,
+ easeInOutBounce: Clutter.AnimationMode.EASE_IN_OUT_BOUNCE,
+ easeOutInBounce: undefined,
+};
+
+function _easeTarget(target, tweeningParameters) {
+ if (!(target instanceof Clutter.Actor))
+ return false;
+
+ let props = Object.assign({}, tweeningParameters);
+ let easingParams = {};
+
+ if (tweeningParameters.hasOwnProperty('time'))
+ easingParams['duration'] = tweeningParameters['time'] * 1000;
+ delete props['time'];
+
+ if (tweeningParameters.hasOwnProperty('delay'))
+ easingParams['delay'] = tweeningParameters['delay'] * 1000;
+ delete props['delay'];
+
+ let mode = Clutter.AnimationMode.EASE_OUT_EXPO;
+ if (tweeningParameters.hasOwnProperty('transition'))
+ mode = transitionTranslations[tweeningParameters['transition']];
+ delete props['transition'];
+
+ if (mode == undefined)
+ return false;
+
+ easingParams['mode'] = mode;
+
+ let getHandler = function(name) {
+ if (!tweeningParameters.hasOwnProperty(name))
+ return null;
+
+ let [handler, scope, params] = [
+ tweeningParameters[name],
+ tweeningParameters[name + 'Scope'] || target,
+ tweeningParameters[name + 'Params'] || []
+ ];
+
+ delete props[name];
+ delete props[name + 'Scope'];
+ delete props[name + 'Params'];
+
+ return () => { handler.apply(scope, params); };
+ }
+
+ let onUpdate = getHandler('onUpdate');
+ if (onUpdate)
+ easingParams['onUpdate'] = onUpdate;
+
+ let onComplete = getHandler('onComplete');
+ let onOverwrite = getHandler('onOverwrite');
+ if (onComplete || onOverwrite)
+ easingParams['onStopped'] = isFinished => {
+ if (!isFinished && onOverwrite)
+ onOverwrite();
+ if (!target._tweensRemoved && onComplete)
+ onComplete();
+ }
+
+ // Implicit animations only work with animatable properties
+ if (Object.keys(props).some(p => !target.find_property(p)))
+ return false;
+
+ target._tweensRemoved = false;
+ target.ease(props, easingParams);
+
+ return true;
+}
+
function addCaller(target, tweeningParameters) {
_wrapTweening(target, tweeningParameters);
@@ -36,6 +147,9 @@ function addCaller(target, tweeningParameters) {
}
function addTween(target, tweeningParameters) {
+ if (_easeTarget(target, tweeningParameters))
+ return;
+
_wrapTweening(target, tweeningParameters);
Tweener.addTween(target, tweeningParameters);
}
@@ -116,6 +230,11 @@ function isTweening(scope) {
}
function removeTweens(scope) {
+ scope._tweensRemoved = true;
+ if (scope instanceof Clutter.Actor)
+ scope.remove_all_transitions();
+ scope._tweensRemoved = false;
+
if (Tweener.removeTweens.apply(null, arguments)) {
// If we just removed the last active tween, clean up
if (Tweener.getTweenCount(scope) == 0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]