ACT J anima code

// ACT J anima
/* ======================================= v 0.6.1
 @ args			obj/string		used as @args->target if is string
	 @ target		obj/string	element or selector
	 @ mode			string		element / items
	 @ delay		float		delay between items (seconds)
	 @ play			string		onLoad / onClick / custom event
	 @ animation	array		array of animation actions [name, duration, value]
 @ animArray	array			used as @args->animation if @args is a string
   ======================================= */
function ACTJanima( args, animArray ){
	animArray = animArray || [];
	const defaults = {
		target	  : '.Janima',
		mode 	  : 'element',  // element, items
		delay	  : 0.1,
		units	  : 'px',
		dir		  : 'in',
		animation : [/* ['name', duration], .. */],
	}
	let animDefaults = { 
		time    : 1,
		offset	: 100,
		scale	: 200,
		blur	: 10,
		rot		: 0,
		fade	: 0,
		x		: 100,
		y		: 100,
		z		: 0,
		ease	: 'ease',
		play	: false, // onLoad, onClick
	}
	const ease = {
		easeIn	  : 'ease-in',
		easeOut	  : 'ease-out',
		easeInOut : 'ease-in-out',
		ease   	  : 'ease',
		linear 	  : 'linear',
		elastic	  : 'cubic-bezier(0.25, 0.00, 0.30, 1.65)',
		elasticOut: 'cubic-bezier(0.00, 0.00, 0.40, 1.35)',
	}
	let $target,
		ITEMS = {},
		anim  = {}; 
	
	
	// Initialize
	init();
	if ( ! $target.length ) return;
	initElements();
	playbackEvents()
	
	
	// --------------------------------------
	function init(){
		args = args || {};
		if ( typeof args == 'string' ) {
			args = {
				target: args,
				animation: animArray,
			};
		}
		args = $.extend(true, {}, defaults, args);

		
		// in default mode, scan for elements with aj- classes and no Janima
		if ( args.target == '.Janima' ) {
			$('[class*="AJ-"]').addClass('Janima')
		}
		
		
		$target = args.target;
		if ( typeof args.target == 'string' ) $target = $( args.target );
		
	}
	function initElements() {
		
		// Loop through targets
		$target.each(function(idx){
			// set id
			let id = 'A-' + $.now() + idx;
			
			let _$targ = $(this)
			if ( _$targ.is('[class*="aj-items"]') ) args.mode = 'items';
			if ( _$targ.is('[class*="AJ-items"]') ) args.mode = 'items';
			_$targ.attr('data-anima', id )


			ITEMS[id] = {
				mode	: args.mode,
				keys	: [],
				values	: [],
			}


			 
			// Parse Animation
			if ( ! parseAnimation( _$targ ) ) return;

			// get values of first step
			getAnimationValues( _$targ, ITEMS[id].values );
			
			// initialize elements
			if ( ITEMS[id].mode == 'element' ) {

				_$targ.css({
					transition : '0s all',
					//visibility : 'hidden',
				})
				initElement( _$targ );

			} else {

				// or initialize children
				_$targ.children().css({
					transition : '0s all',
					//visibility : 'hidden',
				})
				_$targ.children().each(function(idx2){
					$(this).attr('data-anima', id )
					initElement( $(this) );
				})

				
				
	
			}



		})
		
	}
	function parseAnimation( element ){
		animDefaults.x = animDefaults.offset;
		animDefaults.y = animDefaults.offset;
		
		let id  = element.attr('data-anima')
		
		
		// get animation from classes
		if ( element.attr('class') ) {
			let classList = element.attr('class').split(/\s+/);
			classList.forEach(clss =>{
				if ( clss.substr(0,3).toLowerCase() == 'aj-' ) {
					ITEMS[id].values.push( clss.substr(3) );
				}
			})
		}
		
		// get animation from Javascript arguments
		if ( typeof args.animation == 'string' ) args.animation = [ args.animation ]
		if ( args.animation.length ) {
			args.animation.forEach(step =>{
				ITEMS[id].values.push( step );
			})
		}
		
		
		
		if ( ! ITEMS[id].values.length ) return false;
		
		
		
		// parse animation values
		let tmp = []
		ITEMS[id].values.forEach(step =>{
			let values = {}
			step.split('-').forEach(v=>{
				let key = v.split(':')[0];
				let val = v.split(':')[1] || animDefaults[ key ];
				
				if ( key == 'left' ) val = -val || -animDefaults.x;
				if ( key == 'top' )  val = -val || -animDefaults.y;
				
				if ( key == 'left' )  	{ key = 'x'; val = parseFloat( val ) }
				if ( key == 'right' )  	{ key = 'x'; val = parseFloat( val ) }
				if ( key == 'top' )  	{ key = 'y'; val = parseFloat( val ) }
				if ( key == 'bottom' )  { key = 'y'; val = parseFloat( val ) }
				
				if ( typeof val == 'string' ) val = val.replace('__','-')
				if ( typeof val == 'undefined' || val == null || Number.isNaN(val) )
					val = animDefaults[ key ]
				
				
				// play
				if ( key == 'play' )  {
					
					val = val || 'onLoad';
					ITEMS[id].play = val;
				
				// items
				} else if ( key == 'items' ) {
					
					if ( val ) ITEMS[id].delay = parseFloat( val )
					
				// out
				} else if ( key == 'out' ) {
					
					if ( val ) ITEMS[id].dir = 'out';
					
				// rest values
				} else {
					
					values[ key ] = val
				}
			})
			tmp.push( values )
		})
		ITEMS[id].values = tmp;
		

		
		return true;
		
	}
	function getAnimationValues( element, values ){
		let units = '%';
		let id = element.attr('data-anima')

		let XX = 0,
			YY = 0,
			ZZ = 0,
			SC = 1,
			RT = 0,
			BL = 0,
			OP =  1;
		ITEMS[id].keys[0] = {
			transform : `translate3d(0, 0, 0) scale(1) rotate(0deg)`,
			filter	  :	'blur(0px)',
			opacity	  : element.css('opacity') || OP,
		}
		 
		// Loop through animation values
		let idx = 0;
		$.each(values, function(i, animation){
			idx++;
			ITEMS[id].keys[idx] = {
				_time: animDefaults.time,
				_ease: animDefaults.ease,
			}
			$.each(animation, function(key, val){
				// control
				if ( key == 'time' ) ITEMS[id].keys[idx]._time = parseFloat( val );
				if ( key == 'ease' ) ITEMS[id].keys[idx]._ease = ease[ val ];


				// fade
				if ( key == 'fade' ) OP = parseFloat( val );


				// top / bottom
				if ( key == 'y' ) {
					val = parseFloat(val);
					YY = (YY + val);
				}

				// left / right
				if ( key == 'x' ) { 
					val = parseInt(val);
					XX = (XX + val);
				}

				// scale
				if ( key == 'scale' ) SC = parseFloat( val ) / 100;

				// rotation
				if ( key == 'rot' )   RT = parseFloat( val )

				// blur
				if ( key == 'blur' )  BL = parseFloat( val )

			})
			
			let u = args.units
			ITEMS[id].keys[idx].transform =
				`translate3d(${XX+u}, ${YY+u}, ${ZZ+u}) scale(${SC}) rotate(${RT}deg)`
			ITEMS[id].keys[idx].filter = `blur(${BL}px)`;
			ITEMS[id].keys[idx].opacity = OP;

			if (args.dir != 'out' && idx == 1 ) {
				XX = 0; YY = 0; ZZ = 0; SC = 1; RT = 0; BL = 0; OP = 1;
			}
		})
		
		if (args.dir != 'out') {
			let tmp0 = JSON.stringify( ITEMS[id].keys[0] )
			let tmp1 = JSON.stringify( ITEMS[id].keys[1] )
			ITEMS[id].keys[0] = JSON.parse( tmp1 )
			ITEMS[id].keys[1] = JSON.parse( tmp0 )
			ITEMS[id].keys[1]._ease = ITEMS[id].keys[0]._ease
			ITEMS[id].keys[1]._time = ITEMS[id].keys[0]._time
			delete ITEMS[id].keys[0]._ease;
			delete ITEMS[id].keys[0]._time;
		}
		
		return ITEMS[id];
		
		
	}
	function initElement( element ){
		let id  = element.attr('data-anima')
		// Set starting position
		element.css('transition', 'unset');
		$.each(ITEMS[id].keys[0], function(key, val){
			if ( key.substr(0,1) != '_' ) element.css(key, val);
		})

			
	}
	
	// --------------------------------------
	function play( _$target ){
		
		_$target = _$target || $( args.target )
		
		_$target.each(function(){
			let id = $(this).attr('data-anima')
			
			if ( $(this).is('[class*="aj-items"]') ) ITEMS[id].mode = 'items';
			if ( $(this).is('[class*="AJ-items"]') ) ITEMS[id].mode = 'items';
			
			if ( ITEMS[id].mode == 'element' ) animate( $(this) )
			if ( ITEMS[id].mode == 'items' )   animateItems( $(this) )
		})
		
	}
	function playbackEvents(){
		$target.each(function(){
			let _$target = $(this);
			let id = _$target.attr('data-anima')

			if ( ITEMS[id].play ) {
				if ( ITEMS[id].play == 'onLoad' ) play( _$target )
				else if ( ITEMS[id].play == 'onClick' ||
						  ITEMS[id].play == 'click' ) _$target.click( play )
				else {
					if ( ITEMS[id].play == 'reveal' ) ITEMS[id].play = 'revealMid'
					ITEMS[id].play = ITEMS[id].play.replace('__', '-')
					$('body').one(ITEMS[id].play, function(){  play( _$target )  })
					_$target.one( ITEMS[id].play, function(){  play( _$target )  })
				}
			}
		})
	}
	// --------------------------------------
	function animateItems( _target ){
		
		_target.children().each(function(idx){
			setTimeout(e =>{
				animate( $(this) )
			}, idx * args.delay * 1000)
		})
		
	}
	function animate( element ){
		let id = element.attr('data-anima')

		if ( !id ) return;
		let time = 0;
		// Animation Loop
		ITEMS[id].keys.forEach((animation, i) =>{
			if ( i == 0 ) return;
			
			setTimeout(function(element, animation, i){

				applyAnimationValues( element, animation, i )
				
			}, time * 1000, element, animation, i)
			time += parseFloat( animation._time || 0 );
		})
		// Animation End
		//setTimeout( animationEnd, time * 1000 )
		
	}
	function applyAnimationValues( element, animation, idx ){
		let id = element.attr('data-anima')
		element.css('visibility', 'visible')
		element.css('transition', animation._time + 's transform, ' + 
					              animation._time + 's opacity, ' +
					              animation._time + 's filter ' + animation._ease)
		
		$.each(animation, function(key, val){
		
			if ( key.substr(0,1) != '_' ) element.css(key, val)

		})
		
	}
	// --------------------------------------

	
	return {
		play : play,
	}
	
}

Leave a Reply

Your email address will not be published. Required fields are marked *