UNPKG

@gravityforms/utils

Version:
177 lines (160 loc) 4.46 kB
import getHiddenHeight from './get-hidden-height'; /** * @module slide * @description Two simple utils to slide an element up or down from hidden to full height. * */ const options = { timeoutDelay: 25, }; const requestIds = []; const easeFxn = ( t ) => t < 0.2074 // eslint-disable-next-line no-mixed-operators ? -3.8716 * t * t * t + 6.137 * t * t + 0.4 * t // eslint-disable-next-line no-mixed-operators : 1.1317 * ( t - 1 ) * ( t - 1 ) * ( t - 1 ) - // eslint-disable-next-line no-mixed-spaces-and-tabs,no-mixed-operators 0.1975 * ( t - 1 ) * ( t - 1 ) + // eslint-disable-next-line no-mixed-spaces-and-tabs 1; const checkRequestIds = ( id ) => { if ( ! requestIds[ id ] ) { requestIds[ id ] = { up: null, down: null, }; } }; const cancelAnimations = ( id ) => { if ( requestIds[ id ].up ) { window.cancelAnimationFrame( requestIds[ id ].up ); requestIds[ id ].up = null; } if ( requestIds[ id ].down ) { window.cancelAnimationFrame( requestIds[ id ].down ); requestIds[ id ].down = null; } }; /** * @function down * @description A utility to reveal some hidden content with a slide down animation. * Element to slide should get the following CSS: * max-height: 0; * overflow: hidden; * * @since 1.0.0 * * @param {Node|HTMLElement} elem Element to show. * @param {string} id Unique ID of animation. * @param {number} time Length of animation. * @param {Function} callback Callback function. * * @requires getHiddenHeight * * @return {void} * * @example * import { slide } from "@gravityforms/utils"; * * function Example() { * const target = getNodes( 'example' )[ 0 ]; * const callback = () => { * //do something after animation * }; * * slide.down( target, example, 800, callback ); * } * */ export const down = ( elem, id, time = 400, callback = null ) => { const startHeight = elem.offsetHeight; const endHeight = getHiddenHeight( elem ); let startTime = null; elem.style.maxHeight = '0'; checkRequestIds( id ); cancelAnimations( id ); const step = ( timestamp ) => { if ( ! startTime ) { startTime = timestamp; } const timeDiff = timestamp - startTime; const progress = easeFxn( timeDiff / time ); // eslint-disable-next-line no-mixed-operators const height = progress * ( endHeight - startHeight ) + startHeight; elem.style.maxHeight = `${ height }px`; if ( timeDiff < time ) { requestIds[ id ].down = window.requestAnimationFrame( step ); } else { requestIds[ id ].down = null; elem.style.maxHeight = 'none'; if ( callback ) { callback(); } } }; setTimeout( () => { requestIds[ id ].down = window.requestAnimationFrame( step ); }, options.timeoutDelay ); }; /** * @function up * @description A utility to hide some content with a slide up animation. * Element to slide should get the following CSS: * max-height: 0; * overflow: hidden; * * @since 1.0.0 * * @param {Node|HTMLElement} elem Element to hide. * @param {string} id Unique ID of animation. * @param {number} time Length of animation. * @param {Function} callback Callback function. * * @requires getHiddenHeight * * @return {void} * * @example * import { slide } from "@gravityforms/utils"; * * function Example() { * const target = getNodes( 'example' )[ 0 ]; * const callback = () => { * //do something after animation * }; * * slide.up( target, example, 800, callback ); * } * */ export const up = ( elem, id, time = 400, callback = null ) => { const startHeight = elem.offsetHeight; const endHeight = 0; let startTime = null; elem.style.maxHeight = `${ startHeight }px`; checkRequestIds( id ); cancelAnimations( id ); const step = ( timestamp ) => { if ( ! startTime ) { startTime = timestamp; } const timeDiff = timestamp - startTime; const progress = easeFxn( timeDiff / time ); // eslint-disable-next-line no-mixed-operators const height = progress * ( endHeight - startHeight ) + startHeight; elem.style.maxHeight = `${ height }px`; if ( timeDiff < time ) { requestIds[ id ].up = window.requestAnimationFrame( step ); } else { requestIds[ id ].up = null; elem.style.maxHeight = '0'; if ( callback ) { callback(); } } }; setTimeout( () => { requestIds[ id ].up = window.requestAnimationFrame( step ); }, options.timeoutDelay ); };