js: Ease non-animatable actor properties

Properties that aren't marked as animatable don't support *implicit*
animations, but they can still be animated with explicit transitions.
Use the newly added convenience method to cut down further on Tweener
usage.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/666
This commit is contained in:
Florian Müllner 2019-07-25 02:06:05 +02:00
parent ef18f621ac
commit fffe7bdf9c
8 changed files with 135 additions and 157 deletions

View File

@ -11,7 +11,6 @@ const Layout = imports.ui.layout;
const Main = imports.ui.main; const Main = imports.ui.main;
const PageIndicators = imports.ui.pageIndicators; const PageIndicators = imports.ui.pageIndicators;
const PopupMenu = imports.ui.popupMenu; const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
var KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2; var KEYBOARD_REST_TIME = Layout.KEYBOARD_ANIMATION_TIME * 2;
var KEY_LONG_PRESS_TIME = 250; var KEY_LONG_PRESS_TIME = 250;
@ -712,15 +711,13 @@ var EmojiPager = GObject.registerClass({
let relDelta = Math.abs(this._delta - value) / this._width; let relDelta = Math.abs(this._delta - value) / this._width;
let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta); let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta);
Tweener.removeTweens(this); this.remove_all_transitions();
Tweener.addTween(this, this.ease_property('delta', value, {
{ delta: value, duration: time,
time: time / 1000, onComplete: () => {
transition: 'easeInOutQuad', this.setCurrentPage(this.getFollowingPage());
onComplete() { }
this.setCurrentPage(this.getFollowingPage()); });
}
});
} }
} }
@ -728,12 +725,10 @@ var EmojiPager = GObject.registerClass({
let relDelta = Math.abs(this._delta) / this.width; let relDelta = Math.abs(this._delta) / this.width;
let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta); let time = PANEL_SWITCH_ANIMATION_TIME * Math.abs(relDelta);
Tweener.removeTweens(this); this.remove_all_transitions();
Tweener.addTween(this, this.ease_property('delta', 0, {
{ delta: 0, duration: time,
time: time / 1000, });
transition: 'easeInOutQuad',
});
} }
_initPagingInfo() { _initPagingInfo() {

View File

@ -5,7 +5,6 @@ const { Clutter, GObject, Shell, St } = imports.gi;
const Signals = imports.signals; const Signals = imports.signals;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
var DEFAULT_FADE_FACTOR = 0.4; var DEFAULT_FADE_FACTOR = 0.4;
var VIGNETTE_BRIGHTNESS = 0.2; var VIGNETTE_BRIGHTNESS = 0.2;
@ -175,29 +174,31 @@ var Lightbox = class Lightbox {
show(fadeInTime) { show(fadeInTime) {
fadeInTime = fadeInTime || 0; fadeInTime = fadeInTime || 0;
this.actor.remove_all_transitions();
let onComplete = () => {
this.shown = true;
this.emit('shown');
};
if (this._radialEffect) { if (this._radialEffect) {
let effect = this.actor.get_effect('radial'); this.actor.ease_property(
Tweener.removeTweens(effect); '@effects.radial.brightness', VIGNETTE_BRIGHTNESS, {
Tweener.addTween(effect, duration: fadeInTime,
{ brightness: VIGNETTE_BRIGHTNESS, mode: Clutter.AnimationMode.EASE_OUT_QUAD
sharpness: VIGNETTE_SHARPNESS, });
time: fadeInTime / 1000, this.actor.ease_property(
transition: 'easeOutQuad', '@effects.radial.sharpness', VIGNETTE_SHARPNESS, {
onComplete: () => { duration: fadeInTime,
this.shown = true; mode: Clutter.AnimationMode.EASE_OUT_QUAD,
this.emit('shown'); onComplete
} });
});
} else { } else {
this.actor.remove_all_transitions();
this.actor.ease({ this.actor.ease({
opacity: 255 * this._fadeFactor, opacity: 255 * this._fadeFactor,
duration: fadeInTime, duration: fadeInTime,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => { onComplete
this.shown = true;
this.emit('shown');
}
}); });
} }
@ -208,29 +209,28 @@ var Lightbox = class Lightbox {
fadeOutTime = fadeOutTime || 0; fadeOutTime = fadeOutTime || 0;
this.shown = false; this.shown = false;
this.actor.remove_all_transitions();
let onComplete = () => this.actor.hide();
if (this._radialEffect) { if (this._radialEffect) {
let effect = this.actor.get_effect('radial'); this.actor.ease_property(
Tweener.removeTweens(effect); '@effects.radial.brightness', 1.0, {
Tweener.addTween(effect, duration: fadeOutTime,
{ brightness: 1.0, mode: Clutter.AnimationMode.EASE_OUT_QUAD
sharpness: 0.0, });
opacity: 0, this.actor.ease_property(
time: fadeOutTime / 1000, '@effects.radial.sharpness', 0.0, {
transition: 'easeOutQuad', duration: fadeOutTime,
onComplete: () => { mode: Clutter.AnimationMode.EASE_OUT_QUAD,
this.actor.hide(); onComplete
} });
});
} else { } else {
this.actor.remove_all_transitions();
this.actor.ease({ this.actor.ease({
opacity: 0, opacity: 0,
duration: fadeOutTime, duration: fadeOutTime,
mode: Clutter.AnimationMode.EASE_OUT_QUAD, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
onComplete: () => { onComplete
this.actor.hide();
}
}); });
} }
} }

View File

@ -4,7 +4,6 @@ const MessageTray = imports.ui.messageTray;
const Signals = imports.signals; const Signals = imports.signals;
const Calendar = imports.ui.calendar; const Calendar = imports.ui.calendar;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util; const Util = imports.misc.util;
var MESSAGE_ANIMATION_TIME = 100; var MESSAGE_ANIMATION_TIME = 100;
@ -440,10 +439,11 @@ var Message = class Message {
} }
if (animate) { if (animate) {
Tweener.addTween(this._bodyStack.layout_manager, this._bodyStack.ease_property('@layout.expansion', 1, {
{ expansion: 1, progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD,
time: MessageTray.ANIMATION_TIME / 1000, duration: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad' }); });
this._actionBin.scale_y = 0; this._actionBin.scale_y = 0;
this._actionBin.ease({ this._actionBin.ease({
scale_y: 1, scale_y: 1,
@ -460,10 +460,11 @@ var Message = class Message {
unexpand(animate) { unexpand(animate) {
if (animate) { if (animate) {
Tweener.addTween(this._bodyStack.layout_manager, this._bodyStack.ease_property('@layout.expansion', 0, {
{ expansion: 0, progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD,
time: MessageTray.ANIMATION_TIME / 1000, duration: MessageTray.ANIMATION_TIME,
transition: 'easeOutQuad' }); });
this._actionBin.ease({ this._actionBin.ease({
scale_y: 0, scale_y: 0,
duration: MessageTray.ANIMATION_TIME, duration: MessageTray.ANIMATION_TIME,

View File

@ -7,7 +7,6 @@ const Mainloop = imports.mainloop;
const BarLevel = imports.ui.barLevel; const BarLevel = imports.ui.barLevel;
const Layout = imports.ui.layout; const Layout = imports.ui.layout;
const Main = imports.ui.main; const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
var HIDE_TIMEOUT = 1500; var HIDE_TIMEOUT = 1500;
var FADE_TIME = 100; var FADE_TIME = 100;
@ -113,10 +112,10 @@ var OsdWindow = class {
this._level.visible = (value != undefined); this._level.visible = (value != undefined);
if (value != undefined) { if (value != undefined) {
if (this.actor.visible) if (this.actor.visible)
Tweener.addTween(this._level, this._level.ease_property('value', value, {
{ value: value, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
time: LEVEL_ANIMATION_TIME / 1000, duration: LEVEL_ANIMATION_TIME
transition: 'easeOutQuad' }); });
else else
this._level.value = value; this._level.value = value;
} }

View File

@ -13,7 +13,6 @@ const Main = imports.ui.main;
const MessageTray = imports.ui.messageTray; const MessageTray = imports.ui.messageTray;
const OverviewControls = imports.ui.overviewControls; const OverviewControls = imports.ui.overviewControls;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail; const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
// Time for initial animation going into Overview mode // Time for initial animation going into Overview mode
@ -174,24 +173,28 @@ var Overview = class {
_unshadeBackgrounds() { _unshadeBackgrounds() {
let backgrounds = this._backgroundGroup.get_children(); let backgrounds = this._backgroundGroup.get_children();
for (let i = 0; i < backgrounds.length; i++) { for (let i = 0; i < backgrounds.length; i++) {
Tweener.addTween(backgrounds[i], backgrounds[i].ease_property('brightness', 1.0, {
{ brightness: 1.0, duration: SHADE_ANIMATION_TIME,
vignette_sharpness: 0.0, mode: Clutter.AnimationMode.EASE_OUT_QUAD
time: SHADE_ANIMATION_TIME / 1000, });
transition: 'easeOutQuad' backgrounds[i].ease_property('vignette-sharpness', 0.0, {
}); duration: SHADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
} }
} }
_shadeBackgrounds() { _shadeBackgrounds() {
let backgrounds = this._backgroundGroup.get_children(); let backgrounds = this._backgroundGroup.get_children();
for (let i = 0; i < backgrounds.length; i++) { for (let i = 0; i < backgrounds.length; i++) {
Tweener.addTween(backgrounds[i], backgrounds[i].ease_property('brightness', Lightbox.VIGNETTE_BRIGHTNESS, {
{ brightness: Lightbox.VIGNETTE_BRIGHTNESS, duration: SHADE_ANIMATION_TIME,
vignette_sharpness: Lightbox.VIGNETTE_SHARPNESS, mode: Clutter.AnimationMode.EASE_OUT_QUAD
time: SHADE_ANIMATION_TIME / 1000, });
transition: 'easeOutQuad' backgrounds[i].ease_property('vignette-sharpness', Lightbox.VIGNETTE_SHARPNESS, {
}); duration: SHADE_ANIMATION_TIME,
mode: Clutter.AnimationMode.EASE_OUT_QUAD
});
} }
} }

View File

@ -6,7 +6,6 @@ const { Clutter, GObject, Meta, St } = imports.gi;
const Dash = imports.ui.dash; const Dash = imports.ui.dash;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const ViewSelector = imports.ui.viewSelector; const ViewSelector = imports.ui.viewSelector;
const WorkspaceThumbnail = imports.ui.workspaceThumbnail; const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
@ -147,9 +146,10 @@ var SlidingControl = class {
} }
_updateSlide() { _updateSlide() {
Tweener.addTween(this.layout, { slide_x: this._getSlide(), this.actor.ease_property('@layout.slide-x', this._getSlide(), {
time: SIDE_CONTROLS_ANIMATION_TIME / 1000, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
transition: 'easeOutQuad' }); duration: SIDE_CONTROLS_ANIMATION_TIME,
});
} }
getVisibleWidth() { getVisibleWidth() {
@ -185,9 +185,10 @@ var SlidingControl = class {
return; return;
this.layout.translation_x = translationStart; this.layout.translation_x = translationStart;
Tweener.addTween(this.layout, { translation_x: translationEnd, this.actor.ease_property('@layout.translation-x', translationEnd, {
time: SIDE_CONTROLS_ANIMATION_TIME / 1000, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
transition: 'easeOutQuad' }); duration: SIDE_CONTROLS_ANIMATION_TIME,
});
} }
_onOverviewHiding() { _onOverviewHiding() {

View File

@ -12,7 +12,6 @@ const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
const InhibitShortcutsDialog = imports.ui.inhibitShortcutsDialog; const InhibitShortcutsDialog = imports.ui.inhibitShortcutsDialog;
const Main = imports.ui.main; const Main = imports.ui.main;
const ModalDialog = imports.ui.modalDialog; const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const WindowMenu = imports.ui.windowMenu; const WindowMenu = imports.ui.windowMenu;
const PadOsd = imports.ui.padOsd; const PadOsd = imports.ui.padOsd;
const EdgeDragAction = imports.ui.edgeDragAction; const EdgeDragAction = imports.ui.edgeDragAction;
@ -118,17 +117,18 @@ class DisplayChangeDialog extends ModalDialog.ModalDialog {
var WindowDimmer = class { var WindowDimmer = class {
constructor(actor) { constructor(actor) {
this._brightnessEffect = new Clutter.BrightnessContrastEffect({ this._brightnessEffect = new Clutter.BrightnessContrastEffect({
name: 'dim',
enabled: false enabled: false
}); });
actor.add_effect(this._brightnessEffect); actor.add_effect(this._brightnessEffect);
this.actor = actor; this.actor = actor;
this._enabled = true; this._enabled = true;
this._dimFactor = 0.0;
} }
_syncEnabled() { _syncEnabled() {
let animating = this.actor.get_transition('@effects.dim.brightness') != null;
let dimmed = this._brightnessEffect.brightness.red != 127; let dimmed = this._brightnessEffect.brightness.red != 127;
this._brightnessEffect.enabled = (this._enabled && dimmed); this._brightnessEffect.enabled = this._enabled && (animating || dimmed);
} }
setEnabled(enabled) { setEnabled(enabled) {
@ -137,27 +137,16 @@ var WindowDimmer = class {
} }
setDimmed(dimmed, animate) { setDimmed(dimmed, animate) {
let factor = dimmed ? 1.0 : 0.0; let val = 127 * (1 + (dimmed ? 1 : 0) * DIM_BRIGHTNESS);
let color = Clutter.Color.new(val, val, val, 255);
if (animate) { this.actor.ease_property('@effects.dim.brightness', color, {
Tweener.addTween(this, { mode: Clutter.AnimationMode.LINEAR,
_dimFactor: factor, duration: (dimmed ? DIM_TIME : UNDIM_TIME) * (animate ? 1 : 0),
time: (dimmed ? DIM_TIME : UNDIM_TIME) / 1000, onComplete: () => this._syncEnabled()
transition: 'linear', });
onUpdate: () => {
let val = 127 * (1 + this._dimFactor * DIM_BRIGHTNESS); this._syncEnabled();
let color = Clutter.Color.new(val, val, val, 255);
this._brightnessEffect.brightness = color;
this._syncEnabled();
}
});
} else {
this._dimFactor = factor;
let val = 127 * (1 + this._dimFactor * DIM_BRIGHTNESS);
let color = Clutter.Color.new(val, val, val, 255);
this._brightnessEffect.brightness = color;
this._syncEnabled();
}
} }
}; };

View File

@ -8,7 +8,6 @@ const Signals = imports.signals;
const Background = imports.ui.background; const Background = imports.ui.background;
const DND = imports.ui.dnd; const DND = imports.ui.dnd;
const Main = imports.ui.main; const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
const Workspace = imports.ui.workspace; const Workspace = imports.ui.workspace;
const WorkspacesView = imports.ui.workspacesView; const WorkspacesView = imports.ui.workspacesView;
@ -1072,15 +1071,6 @@ var ThumbnailsBox = GObject.registerClass({
} }
} }
_tweenScale() {
Tweener.addTween(this,
{ scale: this._targetScale,
time: RESCALE_ANIMATION_TIME / 1000,
transition: 'easeOutQuad',
onComplete: this._queueUpdateStates,
onCompleteScope: this });
}
_updateStates() { _updateStates() {
this._stateUpdateQueued = false; this._stateUpdateQueued = false;
@ -1092,15 +1082,14 @@ var ThumbnailsBox = GObject.registerClass({
this._iterateStateThumbnails(ThumbnailState.REMOVING, thumbnail => { this._iterateStateThumbnails(ThumbnailState.REMOVING, thumbnail => {
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_OUT); this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_OUT);
Tweener.addTween(thumbnail, thumbnail.ease_property('slide-position', 1, {
{ slide_position: 1, duration: SLIDE_ANIMATION_TIME,
time: SLIDE_ANIMATION_TIME / 1000, mode: Clutter.AnimationMode.LINEAR,
transition: 'linear', onComplete: () => {
onComplete: () => { this._setThumbnailState(thumbnail, ThumbnailState.ANIMATED_OUT);
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATED_OUT); this._queueUpdateStates();
this._queueUpdateStates(); }
} });
});
}); });
// As long as things are sliding out, don't proceed // As long as things are sliding out, don't proceed
@ -1110,25 +1099,28 @@ var ThumbnailsBox = GObject.registerClass({
// Once that's complete, we can start scaling to the new size and collapse any removed thumbnails // Once that's complete, we can start scaling to the new size and collapse any removed thumbnails
this._iterateStateThumbnails(ThumbnailState.ANIMATED_OUT, thumbnail => { this._iterateStateThumbnails(ThumbnailState.ANIMATED_OUT, thumbnail => {
this._setThumbnailState(thumbnail, ThumbnailState.COLLAPSING); this._setThumbnailState(thumbnail, ThumbnailState.COLLAPSING);
Tweener.addTween(thumbnail, thumbnail.ease_property('collapse-fraction', 1, {
{ collapse_fraction: 1, duration: RESCALE_ANIMATION_TIME,
time: RESCALE_ANIMATION_TIME / 1000, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
transition: 'easeOutQuad', onComplete: () => {
onComplete: () => { this._stateCounts[thumbnail.state]--;
this._stateCounts[thumbnail.state]--; thumbnail.state = ThumbnailState.DESTROYED;
thumbnail.state = ThumbnailState.DESTROYED;
let index = this._thumbnails.indexOf(thumbnail); let index = this._thumbnails.indexOf(thumbnail);
this._thumbnails.splice(index, 1); this._thumbnails.splice(index, 1);
thumbnail.destroy(); thumbnail.destroy();
this._queueUpdateStates(); this._queueUpdateStates();
} }
}); });
}); });
if (this._pendingScaleUpdate) { if (this._pendingScaleUpdate) {
this._tweenScale(); this.ease_property('scale', this._targetScale, {
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
duration: RESCALE_ANIMATION_TIME,
onComplete: () => this._queueUpdateStates()
});
this._pendingScaleUpdate = false; this._pendingScaleUpdate = false;
} }
@ -1139,14 +1131,13 @@ var ThumbnailsBox = GObject.registerClass({
// And then slide in any new thumbnails // And then slide in any new thumbnails
this._iterateStateThumbnails(ThumbnailState.NEW, thumbnail => { this._iterateStateThumbnails(ThumbnailState.NEW, thumbnail => {
this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_IN); this._setThumbnailState(thumbnail, ThumbnailState.ANIMATING_IN);
Tweener.addTween(thumbnail, thumbnail.ease_property('slide-position', 0, {
{ slide_position: 0, duration: SLIDE_ANIMATION_TIME,
time: SLIDE_ANIMATION_TIME / 1000, mode: Clutter.AnimationMode.EASE_OUT_QUAD,
transition: 'easeOutQuad', onComplete: () => {
onComplete: () => { this._setThumbnailState(thumbnail, ThumbnailState.NORMAL);
this._setThumbnailState(thumbnail, ThumbnailState.NORMAL); }
} });
});
}); });
} }
@ -1363,14 +1354,13 @@ var ThumbnailsBox = GObject.registerClass({
let indicatorThemeNode = this._indicator.get_theme_node(); let indicatorThemeNode = this._indicator.get_theme_node();
let indicatorTopFullBorder = indicatorThemeNode.get_padding(St.Side.TOP) + indicatorThemeNode.get_border_width(St.Side.TOP); let indicatorTopFullBorder = indicatorThemeNode.get_padding(St.Side.TOP) + indicatorThemeNode.get_border_width(St.Side.TOP);
this.indicator_y = this._indicator.allocation.y1 + indicatorTopFullBorder; this.indicator_y = this._indicator.allocation.y1 + indicatorTopFullBorder;
Tweener.addTween(this, this.ease_property('indicator-y', thumbnail.allocation.y1, {
{ indicator_y: thumbnail.allocation.y1, progress_mode: Clutter.AnimationMode.EASE_OUT_QUAD,
time: WorkspacesView.WORKSPACE_SWITCH_TIME / 1000, duration: WorkspacesView.WORKSPACE_SWITCH_TIME,
transition: 'easeOutQuad', onComplete: () => {
onComplete: () => { this._animatingIndicator = false;
this._animatingIndicator = false; this._queueUpdateStates();
this._queueUpdateStates(); }
} });
});
} }
}); });