87d1248dc1
The environment module is used to initialize the environment, yet it currently also defines the adjustAnimationTime() function. Ideally it should not export any utility functions, in particular once converted to ESM. The function cannot be moved to the existing Utils module, as that depends on an initialized environment, and can therefore not be imported from environment.js, so use that opportunity to group together several animation helpers in a new animationUtils module. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2822>
118 lines
3.4 KiB
JavaScript
118 lines
3.4 KiB
JavaScript
/* exported adjustAnimationTime, ensureActorVisibleInScrollView, wiggle */
|
|
|
|
const St = imports.gi.St;
|
|
const Clutter = imports.gi.Clutter;
|
|
|
|
const Params = imports.misc.params;
|
|
|
|
var SCROLL_TIME = 100;
|
|
|
|
const WIGGLE_OFFSET = 6;
|
|
const WIGGLE_DURATION = 65;
|
|
const N_WIGGLES = 3;
|
|
|
|
/**
|
|
* adjustAnimationTime:
|
|
*
|
|
* @param {number} msecs - time in milliseconds
|
|
*
|
|
* Adjust `msecs` to account for St's enable-animations
|
|
* and slow-down-factor settings
|
|
*/
|
|
function adjustAnimationTime(msecs) {
|
|
const settings = St.Settings.get();
|
|
|
|
if (!settings.enable_animations)
|
|
return 0;
|
|
return settings.slow_down_factor * msecs;
|
|
}
|
|
|
|
/**
|
|
* Animate scrolling a scrollview until an actor is visible.
|
|
*
|
|
* @param {St.ScrollView} scrollView - the scroll view the actor is in
|
|
* @param {Clutter.Actor} actor - the actor
|
|
*/
|
|
function ensureActorVisibleInScrollView(scrollView, actor) {
|
|
const {adjustment} = scrollView.vscroll;
|
|
let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
|
|
|
|
let offset = 0;
|
|
const vfade = scrollView.get_effect('fade');
|
|
if (vfade)
|
|
offset = vfade.fade_margins.top;
|
|
|
|
let box = actor.get_allocation_box();
|
|
let y1 = box.y1, y2 = box.y2;
|
|
|
|
let parent = actor.get_parent();
|
|
while (parent !== scrollView) {
|
|
if (!parent)
|
|
throw new Error('actor not in scroll view');
|
|
|
|
box = parent.get_allocation_box();
|
|
y1 += box.y1;
|
|
y2 += box.y1;
|
|
parent = parent.get_parent();
|
|
}
|
|
|
|
if (y1 < value + offset)
|
|
value = Math.max(0, y1 - offset);
|
|
else if (y2 > value + pageSize - offset)
|
|
value = Math.min(upper, y2 + offset - pageSize);
|
|
else
|
|
return;
|
|
|
|
adjustment.ease(value, {
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
duration: SCROLL_TIME,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* "Wiggles" a clutter actor. A "wiggle" is an animation the moves an actor
|
|
* back and forth on the X axis a specified amount of times.
|
|
*
|
|
* @param {Clutter.Actor} actor - an actor to animate
|
|
* @param {object} params - options for the animation
|
|
* @param {number} params.offset - the offset to move the actor by per-wiggle
|
|
* @param {number} params.duration - the amount of time to move the actor per-wiggle
|
|
* @param {number} params.wiggleCount - the number of times to wiggle the actor
|
|
*/
|
|
function wiggle(actor, params) {
|
|
if (!St.Settings.get().enable_animations)
|
|
return;
|
|
|
|
params = Params.parse(params, {
|
|
offset: WIGGLE_OFFSET,
|
|
duration: WIGGLE_DURATION,
|
|
wiggleCount: N_WIGGLES,
|
|
});
|
|
actor.translation_x = 0;
|
|
|
|
// Accelerate before wiggling
|
|
actor.ease({
|
|
translation_x: -params.offset,
|
|
duration: params.duration,
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
onComplete: () => {
|
|
// Wiggle
|
|
actor.ease({
|
|
translation_x: params.offset,
|
|
duration: params.duration,
|
|
mode: Clutter.AnimationMode.LINEAR,
|
|
repeatCount: params.wiggleCount,
|
|
autoReverse: true,
|
|
onComplete: () => {
|
|
// Decelerate and return to the original position
|
|
actor.ease({
|
|
translation_x: 0,
|
|
duration: params.duration,
|
|
mode: Clutter.AnimationMode.EASE_IN_QUAD,
|
|
});
|
|
},
|
|
});
|
|
},
|
|
});
|
|
}
|