X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/dabe79a438f22612e7d68c8d1de7817505b59b93..refs/pull/3745/head:/resources/js/services/animations.js diff --git a/resources/js/services/animations.js b/resources/js/services/animations.js index 278a765d5..12b8077cf 100644 --- a/resources/js/services/animations.js +++ b/resources/js/services/animations.js @@ -49,7 +49,7 @@ export function slideUp(element, animTime = 400) { const currentPaddingTop = computedStyles.getPropertyValue('padding-top'); const currentPaddingBottom = computedStyles.getPropertyValue('padding-bottom'); const animStyles = { - height: [`${currentHeight}px`, '0px'], + maxHeight: [`${currentHeight}px`, '0px'], overflow: ['hidden', 'hidden'], paddingTop: [currentPaddingTop, '0px'], paddingBottom: [currentPaddingBottom, '0px'], @@ -73,7 +73,7 @@ export function slideDown(element, animTime = 400) { const targetPaddingTop = computedStyles.getPropertyValue('padding-top'); const targetPaddingBottom = computedStyles.getPropertyValue('padding-bottom'); const animStyles = { - height: ['0px', `${targetHeight}px`], + maxHeight: ['0px', `${targetHeight}px`], overflow: ['hidden', 'hidden'], paddingTop: ['0px', targetPaddingTop], paddingBottom: ['0px', targetPaddingBottom], @@ -82,6 +82,38 @@ export function slideDown(element, animTime = 400) { animateStyles(element, animStyles, animTime); } +/** + * Transition the height of the given element between two states. + * Call with first state, and you'll receive a function in return. + * Call the returned function in the second state to animate between those two states. + * If animating to/from 0-height use the slide-up/slide down as easier alternatives. + * @param {Element} element - Element to animate + * @param {Number} animTime - Animation time in ms + * @returns {function} - Function to run in second state to trigger animation. + */ +export function transitionHeight(element, animTime = 400) { + const startHeight = element.getBoundingClientRect().height; + const initialComputedStyles = getComputedStyle(element); + const startPaddingTop = initialComputedStyles.getPropertyValue('padding-top'); + const startPaddingBottom = initialComputedStyles.getPropertyValue('padding-bottom'); + + return () => { + cleanupExistingElementAnimation(element); + const targetHeight = element.getBoundingClientRect().height; + const computedStyles = getComputedStyle(element); + const targetPaddingTop = computedStyles.getPropertyValue('padding-top'); + const targetPaddingBottom = computedStyles.getPropertyValue('padding-bottom'); + const animStyles = { + height: [`${startHeight}px`, `${targetHeight}px`], + overflow: ['hidden', 'hidden'], + paddingTop: [startPaddingTop, targetPaddingTop], + paddingBottom: [startPaddingBottom, targetPaddingBottom], + }; + + animateStyles(element, animStyles, animTime); + }; +} + /** * Animate the css styles of an element using FLIP animation techniques. * Styles must be an object where the keys are style properties, camelcase, and the values