Skip to content

Instantly share code, notes, and snippets.

@jxxe
Created May 3, 2023 05:01
Show Gist options
  • Save jxxe/7dac5d57a85c9ace2051d2051ffda0bf to your computer and use it in GitHub Desktop.
Save jxxe/7dac5d57a85c9ace2051d2051ffda0bf to your computer and use it in GitHub Desktop.
type SmoothAnimationOptions = {
condition: boolean,
addClass?: (node: HTMLElement) => void,
removeClass?: (node: HTMLElement) => void,
animationClass?: string
}
export function smoothAnimation(node: HTMLElement, { condition, addClass, removeClass, animationClass }: SmoothAnimationOptions) {
if(animationClass) {
if(!removeClass) removeClass = () => node.classList.remove(animationClass);
if(!addClass) addClass = () => node.classList.add(animationClass);
}
function onFinish() {
removeClass(node);
setTimeout(() => condition && addClass(node));
}
node.addEventListener('animationend', onFinish);
node.addEventListener('animationiteration', onFinish);
return {
update(newOptions: SmoothAnimationOptions) {
condition = newOptions.condition;
if(condition) addClass(node);
},
destroy() {
removeEventListener('animationend', onFinish);
removeEventListener('animationiteration', onFinish);
}
}
}
@jxxe
Copy link
Author

jxxe commented May 3, 2023

When you remove a class controlling a CSS animation, the element jumps back to its original state without a transition. This Svelte use directive makes it easy to smoothly end discrete or continuous CSS animations. It "rounds" animations up to the nearest iteration.

With Without

Usage

<i use:smoothAnimation={{ condition: loading, animationClass: 'animate-spin' }} class="fas fa-spinner-third"></i>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment