2022-06-09 22:14:38 +00:00
|
|
|
export interface ElementAnimation {
|
2021-05-26 11:32:31 +00:00
|
|
|
keyframes: Keyframe[];
|
2022-06-09 22:14:38 +00:00
|
|
|
rtlKeyframes?: Keyframe[];
|
2021-05-21 21:53:53 +00:00
|
|
|
options?: KeyframeAnimationOptions;
|
|
|
|
}
|
|
|
|
|
2022-06-09 22:14:38 +00:00
|
|
|
export interface ElementAnimationMap {
|
2021-05-21 21:53:53 +00:00
|
|
|
[animationName: string]: ElementAnimation;
|
|
|
|
}
|
|
|
|
|
2022-06-09 22:14:38 +00:00
|
|
|
export interface GetAnimationOptions {
|
|
|
|
/**
|
|
|
|
* The component's directionality. When set to "rtl", `rtlKeyframes` will be preferred over `keyframes` where
|
|
|
|
* available using getAnimation().
|
|
|
|
*/
|
|
|
|
dir: string;
|
|
|
|
}
|
|
|
|
|
2022-01-16 05:47:14 +00:00
|
|
|
const defaultAnimationRegistry = new Map<string, ElementAnimation>();
|
2021-05-21 21:53:53 +00:00
|
|
|
const customAnimationRegistry = new WeakMap<Element, ElementAnimationMap>();
|
|
|
|
|
2021-06-10 13:50:30 +00:00
|
|
|
function ensureAnimation(animation: ElementAnimation | null) {
|
|
|
|
return animation ?? { keyframes: [], options: { duration: 0 } };
|
|
|
|
}
|
|
|
|
|
2022-06-09 22:14:38 +00:00
|
|
|
//
|
|
|
|
// Given an ElementAnimation, this function returns a new ElementAnimation where the keyframes property reflects either
|
|
|
|
// keyframes or rtlKeyframes depending on the specified directionality.
|
|
|
|
//
|
|
|
|
function getLogicalAnimation(animation: ElementAnimation, dir: string) {
|
|
|
|
if (dir.toLowerCase() === 'rtl') {
|
|
|
|
return {
|
|
|
|
keyframes: animation.rtlKeyframes || animation.keyframes,
|
|
|
|
options: animation.options
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return animation;
|
|
|
|
}
|
|
|
|
|
2021-05-21 21:53:53 +00:00
|
|
|
//
|
|
|
|
// Sets a default animation. Components should use the `name.animation` for primary animations and `name.part.animation`
|
2021-05-26 11:32:31 +00:00
|
|
|
// for secondary animations, e.g. `dialog.show` and `dialog.overlay.show`. For modifiers, use `drawer.showTop`.
|
2021-05-21 21:53:53 +00:00
|
|
|
//
|
2021-06-10 13:50:30 +00:00
|
|
|
export function setDefaultAnimation(animationName: string, animation: ElementAnimation | null) {
|
|
|
|
defaultAnimationRegistry.set(animationName, ensureAnimation(animation));
|
2021-05-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Sets a custom animation for the specified element.
|
|
|
|
//
|
2021-06-10 13:50:30 +00:00
|
|
|
export function setAnimation(el: Element, animationName: string, animation: ElementAnimation | null) {
|
2022-01-16 05:47:14 +00:00
|
|
|
customAnimationRegistry.set(el, { ...customAnimationRegistry.get(el), [animationName]: ensureAnimation(animation) });
|
2021-05-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2021-05-26 11:32:31 +00:00
|
|
|
// Gets an element's animation. Falls back to the default if no animation is found.
|
2021-05-21 21:53:53 +00:00
|
|
|
//
|
2022-06-09 22:14:38 +00:00
|
|
|
export function getAnimation(el: Element, animationName: string, options: GetAnimationOptions) {
|
2021-05-21 21:53:53 +00:00
|
|
|
const customAnimation = customAnimationRegistry.get(el);
|
|
|
|
|
|
|
|
// Check for a custom animation
|
2022-01-19 14:37:07 +00:00
|
|
|
if (customAnimation?.[animationName]) {
|
2022-06-09 22:14:38 +00:00
|
|
|
return getLogicalAnimation(customAnimation[animationName], options.dir);
|
2021-05-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for a default animation
|
|
|
|
const defaultAnimation = defaultAnimationRegistry.get(animationName);
|
2022-01-19 14:37:07 +00:00
|
|
|
if (defaultAnimation) {
|
2022-06-09 22:14:38 +00:00
|
|
|
return getLogicalAnimation(defaultAnimation, options.dir);
|
2021-05-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fall back to an empty animation
|
|
|
|
return {
|
|
|
|
keyframes: [],
|
|
|
|
options: { duration: 0 }
|
|
|
|
};
|
|
|
|
}
|