Files
SponsorBlock/src/utils/animationUtils.ts

78 lines
2.5 KiB
TypeScript

/**
* Starts a spinning animation and returns a function to be called when it should be stopped
* The callback will be called when the animation is finished
* It waits until a full rotation is complete
*/
function applyLoadingAnimation(element: HTMLElement, time: number, callback?: () => void): () => Promise<void> {
element.style.animation = `rotate ${time}s 0s infinite`;
return async () => new Promise((resolve) => {
// Make the animation finite
element.style.animation = `rotate ${time}s`;
// When the animation is over, hide the button
const animationEndListener = () => {
if (callback) callback();
element.style.animation = "none";
element.removeEventListener("animationend", animationEndListener);
resolve();
};
element.addEventListener("animationend", animationEndListener);
});
}
function setupCustomHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): { hide: () => void, show: () => void } {
if (enabled) element.classList.add("autoHiding");
element.classList.add("hidden");
element.classList.add("animationDone");
if (!rightSlide) element.classList.add("autoHideLeft");
let mouseEntered = false;
return {
hide: () => {
mouseEntered = false;
if (element.classList.contains("autoHiding")) {
element.classList.add("hidden");
}
},
show: () => {
mouseEntered = true;
element.classList.remove("animationDone");
// Wait for next event loop
setTimeout(() => {
if (mouseEntered) element.classList.remove("hidden")
}, 10);
}
};
}
function setupAutoHideAnimation(element: Element, container: Element, enabled = true, rightSlide = true): void {
const { hide, show } = this.setupCustomHideAnimation(element, container, enabled, rightSlide);
container.addEventListener("mouseleave", () => hide());
container.addEventListener("mouseenter", () => show());
}
function enableAutoHideAnimation(element: Element): void {
element.classList.add("autoHiding");
element.classList.add("hidden");
}
function disableAutoHideAnimation(element: Element): void {
element.classList.remove("autoHiding");
element.classList.remove("hidden");
}
export const AnimationUtils = {
applyLoadingAnimation,
setupAutoHideAnimation,
setupCustomHideAnimation,
enableAutoHideAnimation,
disableAutoHideAnimation
};