655 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			655 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
class ET_Builder_Module_Field_Transform extends ET_Builder_Module_Field_Base {
 | 
						|
 | 
						|
	private $processing_props = array();
 | 
						|
 | 
						|
	public $defaults = array(
 | 
						|
		'scale'     => '100%',
 | 
						|
		'translate' => '0px',
 | 
						|
		'rotate'    => '0deg',
 | 
						|
		'skew'      => '0deg',
 | 
						|
		'origin'    => '50%',
 | 
						|
	);
 | 
						|
 | 
						|
	public $allTransforms = array(
 | 
						|
		'scaleX',
 | 
						|
		'scaleY',
 | 
						|
		'translateX',
 | 
						|
		'translateY',
 | 
						|
		'rotateX',
 | 
						|
		'rotateY',
 | 
						|
		'rotateZ',
 | 
						|
		'skewX',
 | 
						|
		'skewY',
 | 
						|
		'originX',
 | 
						|
		'originY',
 | 
						|
	);
 | 
						|
 | 
						|
	public function get_fields( array $args = array() ) {
 | 
						|
		static $i18n;
 | 
						|
 | 
						|
		if ( ! isset( $i18n ) ) {
 | 
						|
			// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
 | 
						|
			$i18n = array(
 | 
						|
				'scale'     => array(
 | 
						|
					'label' => esc_html__( 'Transform Scale', 'et_builder' ),
 | 
						|
				),
 | 
						|
				'translate' => array(
 | 
						|
					'label' => esc_html__( 'Transform Translate', 'et_builder' ),
 | 
						|
				),
 | 
						|
				'rotate'    => array(
 | 
						|
					'label' => esc_html__( 'Transform Rotate', 'et_builder' ),
 | 
						|
				),
 | 
						|
				'skew'      => array(
 | 
						|
					'label' => esc_html__( 'Transform Skew', 'et_builder' ),
 | 
						|
				),
 | 
						|
				'origin'    => array(
 | 
						|
					'label' => esc_html__( 'Transform Origin', 'et_builder' ),
 | 
						|
				),
 | 
						|
				'styles'    => array(
 | 
						|
					'label'       => esc_html__( 'Transform', 'et_builder' ),
 | 
						|
					'description' => esc_html__( 'Using the transform controls, you can performance visual adjustments to any element using a combination of Scale, Translation, Rotation and Skew settings. This allows you to create advanced design effects without the need of a separate graphic design program.', 'et_builder' ),
 | 
						|
				),
 | 
						|
			);
 | 
						|
			// phpcs:enable
 | 
						|
		}
 | 
						|
 | 
						|
		$settings_args = array(
 | 
						|
			'option_category' => 'layout',
 | 
						|
			'tab_slug'        => 'advanced',
 | 
						|
			'toggle_slug'     => 'transform',
 | 
						|
			'depends_on'      => null,
 | 
						|
			'depends_show_if' => null,
 | 
						|
			'defaults'        => $this->defaults,
 | 
						|
		);
 | 
						|
 | 
						|
		$settings = wp_parse_args( $settings_args, $args );
 | 
						|
 | 
						|
		$additional_options = array();
 | 
						|
		$defaults           = $settings['defaults'];
 | 
						|
 | 
						|
		$tabs = array(
 | 
						|
			'scale'     => array(
 | 
						|
				'icon'     => 'resize',
 | 
						|
				'controls' => array(
 | 
						|
					'transform_scale' => array(
 | 
						|
						'type'           => 'transform',
 | 
						|
						'label'          => $i18n['scale']['label'],
 | 
						|
						'default'        => "{$defaults['scale']}|{$defaults['scale']}",
 | 
						|
						'default_unit'   => '%',
 | 
						|
						'range_settings' => array(
 | 
						|
							'min'  => -100,
 | 
						|
							'max'  => 300,
 | 
						|
							'step' => 1,
 | 
						|
						),
 | 
						|
						'context'        => 'transform_styles',
 | 
						|
						'mobile_options' => true,
 | 
						|
						'sticky'         => true,
 | 
						|
					),
 | 
						|
				),
 | 
						|
			),
 | 
						|
			'translate' => array(
 | 
						|
				'icon'     => 'move',
 | 
						|
				'controls' => array(
 | 
						|
					'transform_translate' => array(
 | 
						|
						'type'           => 'transform',
 | 
						|
						'label'          => $i18n['translate']['label'],
 | 
						|
						'default'        => "{$defaults['translate']}|{$defaults['translate']}",
 | 
						|
						'default_unit'   => 'px',
 | 
						|
						'range_settings' => array(
 | 
						|
							'min'  => -300,
 | 
						|
							'max'  => 300,
 | 
						|
							'step' => 1,
 | 
						|
						),
 | 
						|
						'context'        => 'transform_styles',
 | 
						|
						'mobile_options' => true,
 | 
						|
						'sticky'         => true,
 | 
						|
					),
 | 
						|
				),
 | 
						|
			),
 | 
						|
			'rotate'    => array(
 | 
						|
				'icon'     => 'rotate',
 | 
						|
				'controls' => array(
 | 
						|
					'transform_rotate' => array(
 | 
						|
						'type'           => 'transform',
 | 
						|
						'label'          => $i18n['rotate']['label'],
 | 
						|
						'default'        => "{$defaults['rotate']}|{$defaults['rotate']}|{$defaults['rotate']}",
 | 
						|
						'default_unit'   => 'deg',
 | 
						|
						'range_settings' => array(
 | 
						|
							'min'  => 0,
 | 
						|
							'max'  => 360,
 | 
						|
							'step' => 1,
 | 
						|
						),
 | 
						|
						'context'        => 'transform_styles',
 | 
						|
						'mobile_options' => true,
 | 
						|
						'sticky'         => true,
 | 
						|
					),
 | 
						|
				),
 | 
						|
			),
 | 
						|
			'skew'      => array(
 | 
						|
				'icon'     => 'skew',
 | 
						|
				'controls' => array(
 | 
						|
					'transform_skew' => array(
 | 
						|
						'type'           => 'transform',
 | 
						|
						'label'          => $i18n['skew']['label'],
 | 
						|
						'default'        => "{$defaults['skew']}|{$defaults['skew']}",
 | 
						|
						'default_unit'   => 'deg',
 | 
						|
						'range_settings' => array(
 | 
						|
							'min'       => -180,
 | 
						|
							'max'       => 180,
 | 
						|
							'min_limit' => -180,
 | 
						|
							'max_limit' => 180,
 | 
						|
							'step'      => 1,
 | 
						|
						),
 | 
						|
						'context'        => 'transform_styles',
 | 
						|
						'mobile_options' => true,
 | 
						|
						'sticky'         => true,
 | 
						|
					),
 | 
						|
				),
 | 
						|
			),
 | 
						|
			'origin'    => array(
 | 
						|
				'icon'     => 'transform-origin',
 | 
						|
				'controls' => array(
 | 
						|
					'transform_origin' => array(
 | 
						|
						'type'           => 'transform',
 | 
						|
						'label'          => $i18n['origin']['label'],
 | 
						|
						'default'        => "{$defaults['origin']}|{$defaults['origin']}",
 | 
						|
						'default_unit'   => '%',
 | 
						|
						'range_settings' => array(
 | 
						|
							'min'  => -50,
 | 
						|
							'max'  => 150,
 | 
						|
							'step' => 1,
 | 
						|
						),
 | 
						|
						'context'        => 'transform_styles',
 | 
						|
						'mobile_options' => true,
 | 
						|
						'sticky'         => true,
 | 
						|
					),
 | 
						|
				),
 | 
						|
			),
 | 
						|
		);
 | 
						|
 | 
						|
		$additional_options['transform_styles'] = array(
 | 
						|
			'label'               => $i18n['styles']['label'],
 | 
						|
			'tab_slug'            => $settings['tab_slug'],
 | 
						|
			'toggle_slug'         => $settings['toggle_slug'],
 | 
						|
			'type'                => 'composite',
 | 
						|
			'attr_suffix'         => '',
 | 
						|
			'composite_type'      => 'transforms',
 | 
						|
			'hover'               => 'tabs',
 | 
						|
			'mobile_options'      => true,
 | 
						|
			'sticky'              => true,
 | 
						|
			'responsive'          => true,
 | 
						|
			'bb_support'          => false,
 | 
						|
			'description'         => $i18n['styles']['description'],
 | 
						|
			'composite_structure' => $tabs,
 | 
						|
		);
 | 
						|
 | 
						|
		// Register responsive options
 | 
						|
		$skip       = array(
 | 
						|
			'type'        => 'skip',
 | 
						|
			'tab_slug'    => $settings['tab_slug'],
 | 
						|
			'toggle_slug' => $settings['toggle_slug'],
 | 
						|
		);
 | 
						|
		$linked_skip = $skip + array( 'default' => 'on' );
 | 
						|
 | 
						|
		foreach ( $additional_options['transform_styles']['composite_structure'] as $tab_name => $tab ) {
 | 
						|
			foreach ( $tab['controls'] as $field_name => $field_options ) {
 | 
						|
				$controls                                = $additional_options['transform_styles']['composite_structure'][ $tab_name ]['controls'];
 | 
						|
				$controls[ "{$field_name}_tablet" ]      = $skip;
 | 
						|
				$controls[ "{$field_name}_phone" ]       = $skip;
 | 
						|
				$controls[ "{$field_name}_last_edited" ] = $skip;
 | 
						|
				if ( in_array( $field_name, array( 'transform_scale', 'transform_translate', 'transform_skew' ) ) ) {
 | 
						|
					$controls[ "{$field_name}_linked" ]         = $linked_skip;
 | 
						|
					$controls[ "{$field_name}_linked_tablet" ]  = $linked_skip;
 | 
						|
					$controls[ "{$field_name}_linked_phone" ]   = $linked_skip;
 | 
						|
					$controls[ "{$field_name}_linked__hover" ]  = $linked_skip;
 | 
						|
					$controls[ "{$field_name}_linked__sticky" ] = $linked_skip;
 | 
						|
				}
 | 
						|
				$additional_options['transform_styles']['composite_structure'][ $tab_name ]['controls'] = $controls;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		$additional_options['transform_styles_last_edited'] = $skip;
 | 
						|
 | 
						|
		return $additional_options;
 | 
						|
	}
 | 
						|
 | 
						|
	// Processing functions
 | 
						|
 | 
						|
	public function percent_to_unit( $percent = 0 ) {
 | 
						|
		if ( strpos( $percent, '%' ) === false ) {
 | 
						|
			return $percent;
 | 
						|
		}
 | 
						|
		$value = (float) trim( str_replace( '%', '', $percent ) );
 | 
						|
 | 
						|
		return $value / 100;
 | 
						|
	}
 | 
						|
 | 
						|
	public function set_props( $props ) {
 | 
						|
		$this->processing_props = $props;
 | 
						|
	}
 | 
						|
 | 
						|
	public function get_setting( $value, $default ) {
 | 
						|
		if ( ! empty( $this->processing_props[ $value ] ) ) {
 | 
						|
			return $this->processing_props[ $value ];
 | 
						|
		} else {
 | 
						|
			return $default;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public function get_option( $typeAxis, $type = 'desktop' ) {
 | 
						|
		$setting     = "transform_$typeAxis[0]";
 | 
						|
		$interpreter = array(
 | 
						|
			'X' => 0,
 | 
						|
			'Y' => 1,
 | 
						|
			'Z' => 2,
 | 
						|
		);
 | 
						|
		$index       = $interpreter[ $typeAxis[1] ];
 | 
						|
 | 
						|
		$default_value = false;
 | 
						|
		$option_value  = $this->get_setting( $setting, false );
 | 
						|
 | 
						|
		if ( 'hover' === $type ) {
 | 
						|
			$default_value = $this->get_setting( $setting, false );
 | 
						|
			$option_value  = $this->get_setting( $setting . '__hover', false );
 | 
						|
		} elseif ( 'sticky' === $type ) {
 | 
						|
			$default_value = $this->get_setting( $setting, false );
 | 
						|
			$option_value  = $this->get_setting( $setting . '__sticky', false );
 | 
						|
		} elseif ( 'tablet' === $type ) {
 | 
						|
			$default_value = $this->get_setting( $setting, false );
 | 
						|
			$option_value  = $this->get_setting( $setting . '_tablet', false );
 | 
						|
		} elseif ( 'phone' === $type ) {
 | 
						|
			$default_value = $this->get_setting( $setting . '_tablet', false );
 | 
						|
			$option_value  = $this->get_setting( $setting . '_phone', false );
 | 
						|
			if ( false === $default_value ) {
 | 
						|
				$default_value = $this->get_setting( $setting, false );
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( false === $option_value ) {
 | 
						|
			if ( false !== $default_value ) {
 | 
						|
				$option_value = $default_value;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if ( false === $option_value ) {
 | 
						|
			return '';
 | 
						|
		}
 | 
						|
 | 
						|
		$value_array = explode( '|', $option_value );
 | 
						|
		$value       = $value_array[ $index ];
 | 
						|
 | 
						|
		if ( 'scale' === $typeAxis[0] ) {
 | 
						|
			return $this->percent_to_unit( $value );
 | 
						|
		}
 | 
						|
 | 
						|
		return $value;
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	public function get_elements( $type ) {
 | 
						|
		if ( empty( $this->processing_props ) ) {
 | 
						|
			wp_die( new WP_Error( '666', 'Run set_props first' ) );
 | 
						|
		}
 | 
						|
 | 
						|
		$transformElements = array();
 | 
						|
		$originArray       = array();
 | 
						|
		foreach ( $this->allTransforms as $option ) {
 | 
						|
			$typeAxis    = array();
 | 
						|
			$typeAxis[0] = substr( $option, 0, -1 );
 | 
						|
			$typeAxis[1] = substr( $option, -1 );
 | 
						|
			$value       = esc_attr( $this->get_option( $typeAxis, $type ) );
 | 
						|
			if ( ! empty( $value ) ) {
 | 
						|
				if ( 'origin' === $typeAxis[0] ) {
 | 
						|
					if ( 'originY' === $option && empty( $originArray ) ) {
 | 
						|
						// default value of originX
 | 
						|
						array_push( $originArray, '50%' );
 | 
						|
					}
 | 
						|
					array_push( $originArray, $value );
 | 
						|
				} else {
 | 
						|
					$transformElements[ $option ] = $value;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return array(
 | 
						|
			'transform' => $transformElements,
 | 
						|
			'origin'    => $originArray,
 | 
						|
		);
 | 
						|
	}
 | 
						|
 | 
						|
	public function getTransformDeclaration( $transformElements, $view = 'desktop' ) {
 | 
						|
		$declaration = array();
 | 
						|
		unset( $transformElements['originX'], $transformElements['originY'] );
 | 
						|
		// Perspective is included on when combining with some animations
 | 
						|
		if ( ! empty( $transformElements['perspective'] ) ) {
 | 
						|
			array_push( $declaration, sprintf( 'perspective(%s)', $transformElements['perspective'] ) );
 | 
						|
		}
 | 
						|
		// Transforms must maintain this order to blend correctly with animation rules
 | 
						|
		foreach ( $this->allTransforms as $option ) {
 | 
						|
			if ( ! empty( $transformElements[ $option ] ) ) {
 | 
						|
				array_push( $declaration, sprintf( '%s(%s)', $option, $transformElements[ $option ] ) );
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if ( ! empty( $declaration ) ) {
 | 
						|
 | 
						|
			if ( $this->processing_props['transforms_important'] || 'hover' === $view || 'sticky' === $view ) {
 | 
						|
				array_push( $declaration, '!important' );
 | 
						|
			}
 | 
						|
 | 
						|
			return sprintf( 'transform: %s;', implode( ' ', $declaration ) );
 | 
						|
		}
 | 
						|
 | 
						|
		return '';
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @param $animationType
 | 
						|
	 * @param $elements
 | 
						|
	 * @param $function_name
 | 
						|
	 * @param $device
 | 
						|
	 *
 | 
						|
	 * @return array
 | 
						|
	 */
 | 
						|
	public function transformedAnimation( $animationType, $elements, $function_name, $device ) {
 | 
						|
		if ( 'hover' === $device || 'sticky' === $device ) {
 | 
						|
			return array();
 | 
						|
		}
 | 
						|
 | 
						|
		// phpcs:disable ET.Sniffs.ValidVariableName.VariableNotSnakeCase, ET.Sniffs.ValidVariableName.InterpolatedVariableNotSnakeCase -- Existing codebase
 | 
						|
		$utils                = ET_Core_Data_Utils::instance();
 | 
						|
		$startElements        = $elements['transform'];
 | 
						|
		$responsive           = ET_Builder_Module_Helper_ResponsiveOptions::instance();
 | 
						|
		$direction            = $responsive->get_any_value( $this->processing_props, 'animation_direction', 'center', true, $device );
 | 
						|
		$animation_intensity  = $utils->array_get( $this->processing_props, "animation_intensity_$animationType", 50 );
 | 
						|
		$module_class         = ET_Builder_Element::get_module_order_class( $function_name );
 | 
						|
		$animationName        = "et_pb_{$animationType}_{$direction}_$module_class";
 | 
						|
		$newKeyframe          = "@keyframes $animationName";
 | 
						|
		$newAnimationSelector = ".$module_class.et_animated.transformAnim";
 | 
						|
		$newAnimationRules    = "animation-name: $animationName;";
 | 
						|
		$newKeyframeRules     = '';
 | 
						|
		$transformDeclaration = $this->getTransformDeclaration( $elements['transform'] );
 | 
						|
		$originDeclaration    = sprintf( 'transform-origin:%s;', implode( ' ', $elements['origin'] ) );
 | 
						|
 | 
						|
		$intensity = ! is_numeric( str_replace( '%', '', $animation_intensity ) )
 | 
						|
			? 50
 | 
						|
			: (int) str_replace( '%', '', $animation_intensity );
 | 
						|
 | 
						|
		// slide animation direction center is the same animation as zoom center
 | 
						|
		if ( 'slide' === $animationType && 'center' === $direction ) {
 | 
						|
			$animationType = 'zoom';
 | 
						|
		}
 | 
						|
 | 
						|
		// animation transform gets combined with transform settings as described on et-builder-custom-output.jsx processTransform method
 | 
						|
		switch ( $animationType ) {
 | 
						|
			case 'zoom':
 | 
						|
				$scale                   = ( 100 - $intensity ) * 0.01;
 | 
						|
				$startElements['scaleX'] = $scale * $utils->array_get( $elements['transform'], 'scaleX', 1 );
 | 
						|
				$startElements['scaleY'] = $scale * $utils->array_get( $elements['transform'], 'scaleY', 1 );
 | 
						|
				$startDeclaration        = $this->getTransformDeclaration( $startElements );
 | 
						|
				// replace origin declaration to preserve animation direction setting only if transform origin is not set
 | 
						|
				if ( empty( $elements['origin'] ) ) {
 | 
						|
					$originDeclaration = "transform-origin: $direction;";
 | 
						|
				} else {
 | 
						|
					$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
 | 
						|
				}
 | 
						|
				$newKeyframeRules   = "0%{ $startDeclaration }";
 | 
						|
				$newKeyframeRules  .= "100%{opacity:1;$transformDeclaration}";
 | 
						|
				$newAnimationRules .= $originDeclaration;
 | 
						|
				break;
 | 
						|
			case 'slide':
 | 
						|
				$translateY = $utils->array_get( $elements['transform'], 'translateY', '0%' );
 | 
						|
				$translateX = $utils->array_get( $elements['transform'], 'translateX', '0%' );
 | 
						|
				switch ( $direction ) {
 | 
						|
					case 'top':
 | 
						|
						$startElements['translateY'] = sprintf( 'calc(%s%% + %s)', $intensity * -2, $translateY );
 | 
						|
						$startElements['translateX'] = $translateX;
 | 
						|
						break;
 | 
						|
					case 'bottom':
 | 
						|
						$startElements['translateY'] = sprintf( 'calc(%s%% + %s)', $intensity * 2, $translateY );
 | 
						|
						$startElements['translateX'] = $translateX;
 | 
						|
						break;
 | 
						|
					case 'left':
 | 
						|
						$startElements['translateX'] = sprintf( 'calc(%s%% + %s)', $intensity * -2, $translateX );
 | 
						|
						$startElements['translateY'] = $translateY;
 | 
						|
						break;
 | 
						|
					case 'right':
 | 
						|
						$startElements['translateX'] = sprintf( 'calc(%s%% + %s)', $intensity * 2, $translateX );
 | 
						|
						$startElements['translateY'] = $translateY;
 | 
						|
						break;
 | 
						|
				}
 | 
						|
				$startDeclaration  = $this->getTransformDeclaration( $startElements );
 | 
						|
				$newKeyframeRules  = "0%{ $startDeclaration }";
 | 
						|
				$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
 | 
						|
				break;
 | 
						|
			case 'bounce':
 | 
						|
				$translateX = $utils->array_get( $elements['transform'], 'translateX', '0px' );
 | 
						|
				$translateY = $utils->array_get( $elements['transform'], 'translateY', '0px' );
 | 
						|
				switch ( $direction ) {
 | 
						|
					case 'center':
 | 
						|
						$scaleX = (float) $utils->array_get( $elements['transform'], 'scaleX', 1 );
 | 
						|
						$scaleY = (float) $utils->array_get( $elements['transform'], 'scaleY', 1 );
 | 
						|
 | 
						|
						$newKeyframeRules = 'from, 20%, 40%, 60%, 80%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
 | 
						|
 | 
						|
						$startElements['scaleX'] = 0.3 * $scaleX;
 | 
						|
						$startElements['scaleY'] = 0.3 * $scaleY;
 | 
						|
						$newKeyframeRules       .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['scaleX'] = 1.1 * $scaleX;
 | 
						|
						$startElements['scaleY'] = 1.1 * $scaleY;
 | 
						|
						$newKeyframeRules       .= sprintf( '20%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['scaleX'] = 0.9 * $scaleX;
 | 
						|
						$startElements['scaleY'] = 0.9 * $scaleY;
 | 
						|
						$newKeyframeRules       .= sprintf( '40%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['scaleX'] = 1.03 * $scaleX;
 | 
						|
						$startElements['scaleY'] = 1.03 * $scaleY;
 | 
						|
						$newKeyframeRules       .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['scaleX'] = 0.97 * $scaleX;
 | 
						|
						$startElements['scaleY'] = 0.97 * $scaleY;
 | 
						|
						$newKeyframeRules       .= sprintf( '80%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$newKeyframeRules       .= "100%{opacity: 1;$transformDeclaration}";
 | 
						|
						break;
 | 
						|
					case 'top':
 | 
						|
						$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
 | 
						|
 | 
						|
						$startElements['translateY'] = "calc(-200px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(25px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(-10px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(5px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$newKeyframeRules           .= "100%{opacity: 1;$transformDeclaration}";
 | 
						|
						break;
 | 
						|
					case 'bottom':
 | 
						|
						$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
 | 
						|
 | 
						|
						$startElements['translateY'] = "calc(200px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(-25px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(10px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateY'] = "calc(-5px + $translateY)";
 | 
						|
						$newKeyframeRules           .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$newKeyframeRules           .= "100%{opacity: 1;$transformDeclaration}";
 | 
						|
						break;
 | 
						|
					case 'left':
 | 
						|
						$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
 | 
						|
 | 
						|
						$startElements['translateX'] = "calc(-200px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(25px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(-10px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(5px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$newKeyframeRules           .= "100%{opacity: 1;$transformDeclaration}";
 | 
						|
						break;
 | 
						|
					case 'right':
 | 
						|
						$newKeyframeRules = 'from, 60%, 75%, 90%, to {animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);}';
 | 
						|
 | 
						|
						$startElements['translateX'] = "calc(200px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '0%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(-25px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '60%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(10px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '75%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$startElements['translateX'] = "calc(-5px + $translateX)";
 | 
						|
						$newKeyframeRules           .= sprintf( '90%%{%s}', $this->getTransformDeclaration( $startElements ) );
 | 
						|
						$newKeyframeRules           .= "100%{opacity: 1;$transformDeclaration}";
 | 
						|
						break;
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			case 'flip':
 | 
						|
				$intensityAngle               = ceil( ( 90 / 100 ) * $intensity );
 | 
						|
				$startElements['perspective'] = '2000px';
 | 
						|
 | 
						|
				$rotateX = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateX', '0' ) );
 | 
						|
				$rotateY = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateY', '0' ) );
 | 
						|
				switch ( $direction ) {
 | 
						|
					default:
 | 
						|
					case 'top':
 | 
						|
						$intensityAngle         += $rotateX;
 | 
						|
						$startElement['rotateX'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					case 'bottom':
 | 
						|
						$intensityAngle         *= -1;
 | 
						|
						$intensityAngle         += $rotateX;
 | 
						|
						$startElement['rotateX'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					case 'left':
 | 
						|
						$intensityAngle         *= -1;
 | 
						|
						$intensityAngle         += $rotateY;
 | 
						|
						$startElement['rotateY'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					case 'right':
 | 
						|
						$intensityAngle         += $rotateY;
 | 
						|
						$startElement['rotateY'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
				}
 | 
						|
				$startDeclaration  = $this->getTransformDeclaration( $startElement );
 | 
						|
				$newKeyframeRules  = "0%{ $startDeclaration }";
 | 
						|
				$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'fold':
 | 
						|
				$intensityAngle               = ceil( ( 90 / 100 ) * $intensity );
 | 
						|
				$startElements['perspective'] = '2000px';
 | 
						|
 | 
						|
				$rotateX = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateX', '0' ) );
 | 
						|
				$rotateY = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateY', '0' ) );
 | 
						|
				switch ( $direction ) {
 | 
						|
					case 'top':
 | 
						|
						$intensityAngle          *= -1;
 | 
						|
						$intensityAngle          += $rotateX;
 | 
						|
						$startElements['rotateX'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					case 'bottom':
 | 
						|
						$intensityAngle          += $rotateX;
 | 
						|
						$startElements['rotateX'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					case 'left':
 | 
						|
						$intensityAngle          += $rotateY;
 | 
						|
						$startElements['rotateY'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
					default:
 | 
						|
					case 'right':
 | 
						|
						$intensityAngle          *= -1;
 | 
						|
						$intensityAngle          += $rotateY;
 | 
						|
						$startElements['rotateY'] = "{$intensityAngle}deg";
 | 
						|
						break;
 | 
						|
				}
 | 
						|
				$startDeclaration  = $this->getTransformDeclaration( $startElements );
 | 
						|
				$newKeyframeRules  = "0%{{$startDeclaration}}";
 | 
						|
				$newKeyframeRules .= "100%{opacity:1;{$transformDeclaration}}";
 | 
						|
				// replace origin declaration to preserve animation direction setting only if transform origin is not set
 | 
						|
				if ( empty( $elements['origin'] ) ) {
 | 
						|
					$originDeclaration = "transform-origin: $direction;";
 | 
						|
				} else {
 | 
						|
					$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
 | 
						|
				}
 | 
						|
				$newAnimationRules .= $originDeclaration;
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'roll':
 | 
						|
				$rotateZ        = (float) str_replace( 'deg', '', $utils->array_get( $elements['transform'], 'rotateZ', '0' ) );
 | 
						|
				$intensityAngle = ceil( ( 360 / 100 ) * $intensity );
 | 
						|
 | 
						|
				if ( 'bottom' === $direction || 'right' === $direction ) {
 | 
						|
					$startElements['rotateZ'] = sprintf( '%sdeg', ( $intensityAngle * -1 ) + $rotateZ );
 | 
						|
				} else {
 | 
						|
					$startElements['rotateZ'] = sprintf( '%sdeg', $intensityAngle + $rotateZ );
 | 
						|
				}
 | 
						|
 | 
						|
				$startDeclaration  = $this->getTransformDeclaration( $startElements );
 | 
						|
				$newKeyframeRules  = "0%{ $startDeclaration }";
 | 
						|
				$newKeyframeRules .= "100%{opacity:1;$transformDeclaration}";
 | 
						|
				// replace origin declaration to preserve animation direction setting only if transform origin is not set
 | 
						|
				if ( empty( $elements['origin'] ) ) {
 | 
						|
					$originDeclaration = "transform-origin: $direction;";
 | 
						|
				} else {
 | 
						|
					$originDeclaration = sprintf( 'transform-origin: %s;', implode( ' ', $elements['origin'] ) );
 | 
						|
				}
 | 
						|
				$newAnimationRules .= $originDeclaration;
 | 
						|
				break;
 | 
						|
		}
 | 
						|
 | 
						|
		if ( ! empty( $newKeyframeRules ) ) {
 | 
						|
			return array(
 | 
						|
				'keyframe'       => array(
 | 
						|
					'selector'    => $newKeyframe,
 | 
						|
					'declaration' => $newKeyframeRules,
 | 
						|
				),
 | 
						|
				'animationRules' => array(
 | 
						|
					'selector'    => $newAnimationSelector,
 | 
						|
					'declaration' => $newAnimationRules,
 | 
						|
				),
 | 
						|
				'declaration'    => $transformDeclaration . $originDeclaration,
 | 
						|
			);
 | 
						|
		}
 | 
						|
		// phpcs:enable ET.Sniffs.ValidVariableName.VariableNotSnakeCase, ET.Sniffs.ValidVariableName.InterpolatedVariableNotSnakeCase
 | 
						|
 | 
						|
		return array();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if we need to process transform.
 | 
						|
	 * Here we also check positions since some of it
 | 
						|
	 * requires transform css.
 | 
						|
	 *
 | 
						|
	 * @param array $attrs     Module attributes.
 | 
						|
	 * @param array $positions Position locations.
 | 
						|
	 *
 | 
						|
	 * @return bool
 | 
						|
	 */
 | 
						|
	public function is_used( $attrs, $positions ) {
 | 
						|
		// Check for transform attrs first.
 | 
						|
		foreach ( $attrs as $attr => $value ) {
 | 
						|
			if ( ! $value ) {
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
 | 
						|
			$is_attr = 0 === strpos( $attr, 'transform_' );
 | 
						|
 | 
						|
			if ( $is_attr ) {
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// Then check the current positions.
 | 
						|
		foreach ( $positions as $pos => $value ) {
 | 
						|
			$default_strpos = strpos( $value, '_is_default' );
 | 
						|
			if ( false === $default_strpos ) {
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
return new ET_Builder_Module_Field_Transform();
 |