houser-js-utils
Version:
A comprehensive collection of TypeScript utility functions for common development tasks including array manipulation, string processing, date handling, random number generation, validation, and much more.
306 lines (305 loc) • 10.3 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const AnimationUtils = {
/**
* Animates an element using CSS transitions
* @param element - The HTML element to animate
* @param properties - CSS properties to animate
* @param duration - Animation duration in milliseconds (default: 300)
* @param easing - CSS easing function (default: 'ease')
* @returns Promise that resolves when animation completes
* @example
* ```typescript
* const element = document.querySelector('.box');
* await AnimationUtils.animate(element, {
* transform: 'translateX(100px)',
* opacity: '0.5'
* }, 500, 'ease-in-out');
* ```
*/
animate(element, properties, duration = 300, easing = "ease") {
return new Promise((resolve) => {
Object.keys(properties).forEach((key) => {
const value = properties[key];
if (value !== void 0) {
parseFloat(
getComputedStyle(element)[key]
);
}
});
element.style.transition = `all ${duration}ms ${easing}`;
Object.keys(properties).forEach((key) => {
const value = properties[key];
if (value !== void 0) {
element.style[key] = value;
}
});
const handleTransitionEnd = () => {
element.removeEventListener("transitionend", handleTransitionEnd);
element.style.transition = "";
resolve();
};
element.addEventListener("transitionend", handleTransitionEnd);
setTimeout(handleTransitionEnd, duration);
});
},
/**
* Animates an element using requestAnimationFrame for smoother animations
* @param element - The HTML element to animate
* @param properties - CSS properties to animate
* @param duration - Animation duration in milliseconds (default: 300)
* @param easing - Custom easing function (default: linear)
* @returns Promise that resolves when animation completes
* @example
* ```typescript
* const element = document.querySelector('.box');
* await AnimationUtils.animateWithRAF(element, {
* transform: 'translateX(100px)'
* }, 500, (t) => t * t); // Quadratic easing
* ```
*/
animateWithRAF(element, properties, duration = 300, easing = (t) => t) {
return new Promise((resolve) => {
const startTime = performance.now();
const startValues = {};
const endValues = {};
Object.keys(properties).forEach((key) => {
const value = properties[key];
if (value !== void 0) {
const startValue = parseFloat(
getComputedStyle(element)[key]
);
const endValue = parseFloat(value);
if (!isNaN(startValue) && !isNaN(endValue)) {
startValues[key] = startValue;
endValues[key] = endValue;
}
}
});
const animate = (currentTime) => {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easing(progress);
Object.keys(startValues).forEach((key) => {
const startValue = startValues[key];
const endValue = endValues[key];
const currentValue = startValue + (endValue - startValue) * easedProgress;
element.style[key] = `${currentValue}px`;
});
if (progress < 1) {
requestAnimationFrame(animate);
} else {
resolve();
}
};
requestAnimationFrame(animate);
});
},
/**
* Creates a keyframe animation using the Web Animations API
* @param element - The HTML element to animate
* @param keyframes - Array of keyframe objects
* @param options - Animation options
* @returns Animation object
* @example
* ```typescript
* const element = document.querySelector('.box');
* const animation = AnimationUtils.createKeyframeAnimation(element, [
* { transform: 'translateX(0)', opacity: 1 },
* { transform: 'translateX(100px)', opacity: 0.5 }
* ], {
* duration: 500,
* easing: 'ease-in-out'
* });
* ```
*/
createKeyframeAnimation(element, keyframes, options = {}) {
return element.animate(keyframes, {
duration: 300,
easing: "ease",
fill: "forwards",
...options
});
},
/**
* Creates a spring physics-based animation
* @param element - The HTML element to animate
* @param properties - CSS properties to animate
* @param options - Spring animation configuration
* @returns Promise that resolves when animation completes
* @example
* ```typescript
* const element = document.querySelector('.box');
* await AnimationUtils.createSpringAnimation(element, {
* transform: 'translateY(200px)'
* }, {
* stiffness: 170,
* damping: 26,
* mass: 1
* });
* ```
*/
createSpringAnimation(element, properties, options = {}) {
const { stiffness = 170, damping = 26, mass = 1, duration = 300 } = options;
return new Promise((resolve) => {
const startTime = performance.now();
const startValues = {};
const endValues = {};
const velocities = {};
Object.keys(properties).forEach((key) => {
const value = properties[key];
if (value !== void 0) {
const startValue = parseFloat(
getComputedStyle(element)[key]
);
const endValue = parseFloat(value);
if (!isNaN(startValue) && !isNaN(endValue)) {
startValues[key] = startValue;
endValues[key] = endValue;
velocities[key] = 0;
}
}
});
const animate = (currentTime) => {
const elapsed = currentTime - startTime;
if (elapsed >= duration) {
Object.keys(endValues).forEach((key) => {
element.style[key] = `${endValues[key]}px`;
});
resolve();
return;
}
Object.keys(startValues).forEach((key) => {
const startValue = startValues[key];
const endValue = endValues[key];
const currentValue = parseFloat(
element.style[key] || startValue
);
const velocity = velocities[key];
const displacement = endValue - currentValue;
const spring = stiffness * displacement;
const damper = damping * velocity;
const acceleration = (spring - damper) / mass;
velocities[key] = velocity + acceleration * (elapsed / 1e3);
const newValue = currentValue + velocities[key] * (elapsed / 1e3);
element.style[key] = `${newValue}px`;
});
requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
});
},
/**
* Gets all animations currently running on an element
* @param element - The HTML element to check
* @returns Array of Animation objects
* @example
* ```typescript
* const element = document.querySelector('.box');
* const animations = AnimationUtils.getAnimations(element);
* ```
*/
getAnimations(element) {
return element.getAnimations();
},
/**
* Gets the current animation state of an element
* @param element - The HTML element to check
* @returns Current animation state: 'idle', 'running', or 'paused'
* @example
* ```typescript
* const element = document.querySelector('.box');
* const state = AnimationUtils.getAnimationState(element);
* if (state === 'running') {
* console.log('Element is currently animating');
* }
* ```
*/
getAnimationState(element) {
const animations = element.getAnimations();
if (animations.length === 0) {
return "idle";
}
return animations.some((animation) => animation.playState === "running") ? "running" : "paused";
},
/**
* Checks if an element has any active animations
* @param element - The HTML element to check
* @returns True if the element has any animations
* @example
* ```typescript
* const element = document.querySelector('.box');
* if (AnimationUtils.hasAnimations(element)) {
* console.log('Element has active animations');
* }
* ```
*/
hasAnimations(element) {
return element.getAnimations().length > 0;
},
/**
* Pauses all animations on an element
* @param element - The HTML element to pause animations on
* @example
* ```typescript
* const element = document.querySelector('.box');
* AnimationUtils.pauseAnimations(element);
* ```
*/
pauseAnimations(element) {
element.getAnimations().forEach((animation) => animation.pause());
},
/**
* Resumes all paused animations on an element
* @param element - The HTML element to resume animations on
* @example
* ```typescript
* const element = document.querySelector('.box');
* AnimationUtils.resumeAnimations(element);
* ```
*/
resumeAnimations(element) {
element.getAnimations().forEach((animation) => animation.play());
},
/**
* Reverses the direction of all animations on an element
* @param element - The HTML element to reverse animations on
* @example
* ```typescript
* const element = document.querySelector('.box');
* AnimationUtils.reverseAnimations(element);
* ```
*/
reverseAnimations(element) {
element.getAnimations().forEach((animation) => animation.reverse());
},
/**
* Stops and removes all animations from an element
* @param element - The HTML element to stop animations on
* @example
* ```typescript
* const element = document.querySelector('.box');
* AnimationUtils.stopAnimations(element);
* ```
*/
stopAnimations(element) {
element.getAnimations().forEach((animation) => animation.cancel());
},
/**
* Waits for all animations on an element to complete
* @param element - The HTML element to wait for
* @returns Promise that resolves when all animations complete
* @example
* ```typescript
* const element = document.querySelector('.box');
* await AnimationUtils.waitForAnimations(element);
* console.log('All animations completed');
* ```
*/
async waitForAnimations(element) {
const animations = element.getAnimations();
await Promise.all(animations.map((animation) => animation.finished));
}
};
exports.AnimationUtils = AnimationUtils;
//# sourceMappingURL=AnimationUtils.js.map