UNPKG

@ngfly/carousel

Version:

A smooth, customizable carousel component for Angular 17+ applications

138 lines 16.6 kB
/** * Easing functions for animations */ export const easings = { linear: (t) => t, ease: (t) => t, easeInQuad: (t) => t * t, easeOutQuad: (t) => t * (2 - t), easeInOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t, easeInCubic: (t) => t * t * t, easeOutCubic: (t) => (--t) * t * t + 1, easeInOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1, }; /** * Converts a CSS timing function to its JavaScript equivalent * @param timingFunction CSS timing function string */ export function getCssTimingFunction(timingFunction) { switch (timingFunction) { case 'linear': return easings.linear; case 'ease-in': return easings.easeInQuad; case 'ease-out': return easings.easeOutQuad; case 'ease-in-out': return easings.easeInOutQuad; case 'ease': return easings.ease; default: return easings.easeInOutQuad; } } /** * Creates a CSS transform string for translating elements * * @param position - Translation position in pixels * @param isVertical - Whether to use vertical translation * @returns CSS transform string */ export function createTranslation(position, isVertical) { return isVertical ? `translateY(-${position}px)` : `translateX(-${position}px)`; } /** * Parse time string to milliseconds * @param time Time string in the format: '300ms' or '0.3s' * @param defaultValue Default value in ms * @returns Time in milliseconds */ export function parseTimeToMs(time, defaultValue = 300) { if (!time) return defaultValue; if (time.endsWith('ms')) { return parseInt(time, 10); } else if (time.endsWith('s')) { return parseFloat(time) * 1000; } return parseInt(time, 10) || defaultValue; } /** * Calculate scroll amount based on configuration * @param scrollSize Scroll size specification * @param containerSize Container width or height * @param scrollSizeMap Map of predefined scroll sizes * @param defaultPercentage Default percentage if no size specified * @returns Scroll amount in pixels */ export function calculateScrollAmount(scrollSize, containerSize, scrollSizeMap, defaultPercentage = 0.8) { if (!scrollSize) return containerSize * defaultPercentage; // If size is a percentage if (scrollSize.endsWith('%')) { const percentage = parseFloat(scrollSize) / 100; return containerSize * percentage; } // If size is a predefined value if (scrollSizeMap[scrollSize]) { return scrollSizeMap[scrollSize]; } // If size is a pixel value if (scrollSize.endsWith('px')) { return parseFloat(scrollSize); } return containerSize * defaultPercentage; } /** * Performs a smooth scroll animation * @param element Element to scroll * @param to Target scroll position * @param duration Duration in milliseconds * @param easing Easing function */ export function smoothScroll(element, to, duration = 300, easing = easings.easeInOutQuad) { return new Promise(resolve => { const start = element.scrollLeft; const change = to - start; const startTime = performance.now(); function animateScroll(currentTime) { const elapsedTime = currentTime - startTime; if (elapsedTime >= duration) { element.scrollLeft = to; resolve(); return; } const progress = elapsedTime / duration; const easedProgress = easing(progress); element.scrollLeft = start + change * easedProgress; requestAnimationFrame(animateScroll); } requestAnimationFrame(animateScroll); }); } /** * Performs a smooth vertical scroll animation * @param element Element to scroll * @param to Target scroll position * @param duration Duration in milliseconds * @param easing Easing function */ export function smoothScrollVertical(element, to, duration = 300, easing = easings.easeInOutQuad) { return new Promise(resolve => { const start = element.scrollTop; const change = to - start; const startTime = performance.now(); function animateScroll(currentTime) { const elapsedTime = currentTime - startTime; if (elapsedTime >= duration) { element.scrollTop = to; resolve(); return; } const progress = elapsedTime / duration; const easedProgress = easing(progress); element.scrollTop = start + change * easedProgress; requestAnimationFrame(animateScroll); } requestAnimationFrame(animateScroll); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5pbWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi91dGlscy9hbmltYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUc7SUFDckIsTUFBTSxFQUFFLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3hCLElBQUksRUFBRSxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN0QixVQUFVLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ2hDLFdBQVcsRUFBRSxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QyxhQUFhLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUN4RSxXQUFXLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUNyQyxZQUFZLEVBQUUsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7SUFDOUMsY0FBYyxFQUFFLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FB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LFFBQVEsQ0FBQyxDQUFDO1lBQ3ZDLE9BQU8sQ0FBQyxTQUFTLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxhQUFhLENBQUM7WUFFbkQscUJBQXFCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUVELHFCQUFxQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRWFzaW5nIGZ1bmN0aW9ucyBmb3IgYW5pbWF0aW9uc1xuICovXG5leHBvcnQgY29uc3QgZWFzaW5ncyA9IHtcbiAgbGluZWFyOiAodDogbnVtYmVyKSA9PiB0LFxuICBlYXNlOiAodDogbnVtYmVyKSA9PiB0LFxuICBlYXNlSW5RdWFkOiAodDogbnVtYmVyKSA9PiB0ICogdCxcbiAgZWFzZU91dFF1YWQ6ICh0OiBudW1iZXIpID0+IHQgKiAoMiAtIHQpLFxuICBlYXNlSW5PdXRRdWFkOiAodDogbnVtYmVyKSA9PiB0IDwgMC41ID8gMiAqIHQgKiB0IDogLTEgKyAoNCAtIDIgKiB0KSAqIHQsXG4gIGVhc2VJbkN1YmljOiAodDogbnVtYmVyKSA9PiB0ICogdCAqIHQsXG4gIGVhc2VPdXRDdWJpYzogKHQ6IG51bWJlcikgPT4gKC0tdCkgKiB0ICogdCArIDEsXG4gIGVhc2VJbk91dEN1YmljOiAodDogbnVtYmVyKSA9PiB0IDwgMC41ID8gNCAqIHQgKiB0ICogdCA6ICh0IC0gMSkgKiAoMiAqIHQgLSAyKSAqICgyICogdCAtIDIpICsgMSxcbn07XG5cbi8qKlxuICogQ29udmVydHMgYSBDU1MgdGltaW5nIGZ1bmN0aW9uIHRvIGl0cyBKYXZhU2NyaXB0IGVxdWl2YWxlbnRcbiAqIEBwYXJhbSB0aW1pbmdGdW5jdGlvbiBDU1MgdGltaW5nIGZ1bmN0aW9uIHN0cmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3NzVGltaW5nRnVuY3Rpb24odGltaW5nRnVuY3Rpb246IHN0cmluZyk6ICh0OiBudW1iZXIpID0+IG51bWJlciB7XG4gIHN3aXRjaCAodGltaW5nRnVuY3Rpb24pIHtcbiAgICBjYXNlICdsaW5lYXInOiByZXR1cm4gZWFzaW5ncy5saW5lYXI7XG4gICAgY2FzZSAnZWFzZS1pbic6IHJldHVybiBlYXNpbmdzLmVhc2VJblF1YWQ7XG4gICAgY2FzZSAnZWFzZS1vdXQnOiByZXR1cm4gZWFzaW5ncy5lYXNlT3V0UXVhZDtcbiAgICBjYXNlICdlYXNlLWluLW91dCc6IHJldHVybiBlYXNpbmdzLmVhc2VJbk91dFF1YWQ7XG4gICAgY2FzZSAnZWFzZSc6IHJldHVybiBlYXNpbmdzLmVhc2U7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBlYXNpbmdzLmVhc2VJbk91dFF1YWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgQ1NTIHRyYW5zZm9ybSBzdHJpbmcgZm9yIHRyYW5zbGF0aW5nIGVsZW1lbnRzXG4gKiBcbiAqIEBwYXJhbSBwb3NpdGlvbiAtIFRyYW5zbGF0aW9uIHBvc2l0aW9uIGluIHBpeGVsc1xuICogQHBhcmFtIGlzVmVydGljYWwgLSBXaGV0aGVyIHRvIHVzZSB2ZXJ0aWNhbCB0cmFuc2xhdGlvblxuICogQHJldHVybnMgQ1NTIHRyYW5zZm9ybSBzdHJpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zbGF0aW9uKHBvc2l0aW9uOiBudW1iZXIsIGlzVmVydGljYWw6IGJvb2xlYW4pOiBzdHJpbmcge1xuICByZXR1cm4gaXNWZXJ0aWNhbCBcbiAgICA/IGB0cmFuc2xhdGVZKC0ke3Bvc2l0aW9ufXB4KWAgXG4gICAgOiBgdHJhbnNsYXRlWCgtJHtwb3NpdGlvbn1weClgO1xufVxuXG4vKipcbiAqIFBhcnNlIHRpbWUgc3RyaW5nIHRvIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHRpbWUgVGltZSBzdHJpbmcgaW4gdGhlIGZvcm1hdDogJzMwMG1zJyBvciAnMC4zcydcbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgRGVmYXVsdCB2YWx1ZSBpbiBtc1xuICogQHJldHVybnMgVGltZSBpbiBtaWxsaXNlY29uZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVGltZVRvTXModGltZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBkZWZhdWx0VmFsdWU6IG51bWJlciA9IDMwMCk6IG51bWJlciB7XG4gIGlmICghdGltZSkgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgXG4gIGlmICh0aW1lLmVuZHNXaXRoKCdtcycpKSB7XG4gICAgcmV0dXJuIHBhcnNlSW50KHRpbWUsIDEwKTtcbiAgfSBlbHNlIGlmICh0aW1lLmVuZHNXaXRoKCdzJykpIHtcbiAgICByZXR1cm4gcGFyc2VGbG9hdCh0aW1lKSAqIDEwMDA7XG4gIH1cbiAgXG4gIHJldHVybiBwYXJzZUludCh0aW1lLCAxMCkgfHwgZGVmYXVsdFZhbHVlO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBzY3JvbGwgYW1vdW50IGJhc2VkIG9uIGNvbmZpZ3VyYXRpb25cbiAqIEBwYXJhbSBzY3JvbGxTaXplIFNjcm9sbCBzaXplIHNwZWNpZmljYXRpb25cbiAqIEBwYXJhbSBjb250YWluZXJTaXplIENvbnRhaW5lciB3aWR0aCBvciBoZWlnaHRcbiAqIEBwYXJhbSBzY3JvbGxTaXplTWFwIE1hcCBvZiBwcmVkZWZpbmVkIHNjcm9sbCBzaXplc1xuICogQHBhcmFtIGRlZmF1bHRQZXJjZW50YWdlIERlZmF1bHQgcGVyY2VudGFnZSBpZiBubyBzaXplIHNwZWNpZmllZFxuICogQHJldHVybnMgU2Nyb2xsIGFtb3VudCBpbiBwaXhlbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNjcm9sbEFtb3VudChcbiAgc2Nyb2xsU2l6ZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBcbiAgY29udGFpbmVyU2l6ZTogbnVtYmVyLFxuICBzY3JvbGxTaXplTWFwOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+LFxuICBkZWZhdWx0UGVyY2VudGFnZTogbnVtYmVyID0gMC44XG4pOiBudW1iZXIge1xuICBpZiAoIXNjcm9sbFNpemUpIHJldHVybiBjb250YWluZXJTaXplICogZGVmYXVsdFBlcmNlbnRhZ2U7XG4gIFxuICAvLyBJZiBzaXplIGlzIGEgcGVyY2VudGFnZVxuICBpZiAoc2Nyb2xsU2l6ZS5lbmRzV2l0aCgnJScpKSB7XG4gICAgY29uc3QgcGVyY2VudGFnZTogbnVtYmVyID0gcGFyc2VGbG9hdChzY3JvbGxTaXplKSAvIDEwMDtcbiAgICByZXR1cm4gY29udGFpbmVyU2l6ZSAqIHBlcmNlbnRhZ2U7XG4gIH1cbiAgXG4gIC8vIElmIHNpemUgaXMgYSBwcmVkZWZpbmVkIHZhbHVlXG4gIGlmIChzY3JvbGxTaXplTWFwW3Njcm9sbFNpemVdKSB7XG4gICAgcmV0dXJuIHNjcm9sbFNpemVNYXBbc2Nyb2xsU2l6ZV07XG4gIH1cbiAgXG4gIC8vIElmIHNpemUgaXMgYSBwaXhlbCB2YWx1ZVxuICBpZiAoc2Nyb2xsU2l6ZS5lbmRzV2l0aCgncHgnKSkge1xuICAgIHJldHVybiBwYXJzZUZsb2F0KHNjcm9sbFNpemUpO1xuICB9XG4gIFxuICByZXR1cm4gY29udGFpbmVyU2l6ZSAqIGRlZmF1bHRQZXJjZW50YWdlO1xufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgc21vb3RoIHNjcm9sbCBhbmltYXRpb25cbiAqIEBwYXJhbSBlbGVtZW50IEVsZW1lbnQgdG8gc2Nyb2xsXG4gKiBAcGFyYW0gdG8gVGFyZ2V0IHNjcm9sbCBwb3NpdGlvblxuICogQHBhcmFtIGR1cmF0aW9uIER1cmF0aW9uIGluIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIGVhc2luZyBFYXNpbmcgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNtb290aFNjcm9sbChcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gIHRvOiBudW1iZXIsXG4gIGR1cmF0aW9uOiBudW1iZXIgPSAzMDAsXG4gIGVhc2luZzogKHQ6IG51bWJlcikgPT4gbnVtYmVyID0gZWFzaW5ncy5lYXNlSW5PdXRRdWFkXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gZWxlbWVudC5zY3JvbGxMZWZ0O1xuICAgIGNvbnN0IGNoYW5nZSA9IHRvIC0gc3RhcnQ7XG4gICAgY29uc3Qgc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgXG4gICAgZnVuY3Rpb24gYW5pbWF0ZVNjcm9sbChjdXJyZW50VGltZTogbnVtYmVyKSB7XG4gICAgICBjb25zdCBlbGFwc2VkVGltZSA9IGN1cnJlbnRUaW1lIC0gc3RhcnRUaW1lO1xuICAgICAgaWYgKGVsYXBzZWRUaW1lID49IGR1cmF0aW9uKSB7XG4gICAgICAgIGVsZW1lbnQuc2Nyb2xsTGVmdCA9IHRvO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBlbGFwc2VkVGltZSAvIGR1cmF0aW9uO1xuICAgICAgY29uc3QgZWFzZWRQcm9ncmVzcyA9IGVhc2luZyhwcm9ncmVzcyk7XG4gICAgICBlbGVtZW50LnNjcm9sbExlZnQgPSBzdGFydCArIGNoYW5nZSAqIGVhc2VkUHJvZ3Jlc3M7XG4gICAgICBcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlU2Nyb2xsKTtcbiAgICB9XG4gICAgXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGFuaW1hdGVTY3JvbGwpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBQZXJmb3JtcyBhIHNtb290aCB2ZXJ0aWNhbCBzY3JvbGwgYW5pbWF0aW9uXG4gKiBAcGFyYW0gZWxlbWVudCBFbGVtZW50IHRvIHNjcm9sbFxuICogQHBhcmFtIHRvIFRhcmdldCBzY3JvbGwgcG9zaXRpb25cbiAqIEBwYXJhbSBkdXJhdGlvbiBEdXJhdGlvbiBpbiBtaWxsaXNlY29uZHNcbiAqIEBwYXJhbSBlYXNpbmcgRWFzaW5nIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzbW9vdGhTY3JvbGxWZXJ0aWNhbChcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQsXG4gIHRvOiBudW1iZXIsXG4gIGR1cmF0aW9uOiBudW1iZXIgPSAzMDAsXG4gIGVhc2luZzogKHQ6IG51bWJlcikgPT4gbnVtYmVyID0gZWFzaW5ncy5lYXNlSW5PdXRRdWFkXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgIGNvbnN0IHN0YXJ0ID0gZWxlbWVudC5zY3JvbGxUb3A7XG4gICAgY29uc3QgY2hhbmdlID0gdG8gLSBzdGFydDtcbiAgICBjb25zdCBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICBcbiAgICBmdW5jdGlvbiBhbmltYXRlU2Nyb2xsKGN1cnJlbnRUaW1lOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IGVsYXBzZWRUaW1lID0gY3VycmVudFRpbWUgLSBzdGFydFRpbWU7XG4gICAgICBpZiAoZWxhcHNlZFRpbWUgPj0gZHVyYXRpb24pIHtcbiAgICAgICAgZWxlbWVudC5zY3JvbGxUb3AgPSB0bztcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIGNvbnN0IHByb2dyZXNzID0gZWxhcHNlZFRpbWUgLyBkdXJhdGlvbjtcbiAgICAgIGNvbnN0IGVhc2VkUHJvZ3Jlc3MgPSBlYXNpbmcocHJvZ3Jlc3MpO1xuICAgICAgZWxlbWVudC5zY3JvbGxUb3AgPSBzdGFydCArIGNoYW5nZSAqIGVhc2VkUHJvZ3Jlc3M7XG4gICAgICBcbiAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlU2Nyb2xsKTtcbiAgICB9XG4gICAgXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGFuaW1hdGVTY3JvbGwpO1xuICB9KTtcbn0gIl19