utils/animation/animateMove.js

import customEvent from '../customEvent';

/**
 * A transition animation where by an element moves from its origin position
 * to a designated position
 *
 * @param {HTMLElement} $original - Original element
 * @param {HTMLElement} $destination - Destination element (location and size to transition to)
 * @param {Integer} duration - animation duration
 *
 * @method animateMove
 */
const animateMove = ( $origin, $destination, duration = 0.35 ) => {
	const {
		top: destTop, left: destLeft, width: destWidth,
	} = $destination.getBoundingClientRect();

	const {
		top, left, width, height,
	} = $origin.getBoundingClientRect();

	const $transition = document.createElement( 'div' );
	$transition.classList.add( 'animate-move' );
	$origin.setAttribute( 'style', `width: ${width}px; height: ${height}px` );
	$transition.appendChild( $origin );
	$transition.setAttribute( 'style', `transform:translate( ${left}px, ${top}px );transition-duration:${duration}s;` );

	const $body = document.querySelector( 'body' );
	$body.appendChild( $transition );

	setTimeout( () => {
		const scale = Math.round( ( destWidth / width ) * 100 ) / 100;
		$transition.setAttribute( 'style', `width:${width}px; height:${height}px; opacity: 0; transform: translate( ${destLeft}px, ${destTop}px ) scale(${scale});` );

		setTimeout( () => {
			$transition.parentNode.removeChild( $transition ); // IE11 doesn't support remove()

			customEvent.fire( $origin, customEvent.TRANSITION_COMPLETED );
		}, duration * 1000 );
	}, 1 );
};

export default animateMove;