878 lines
24 KiB
PHP
878 lines
24 KiB
PHP
<?php
|
|
namespace ElementorPro\Modules\PageTransitions;
|
|
|
|
use Elementor\Controls_Manager;
|
|
use Elementor\Controls_Stack;
|
|
use Elementor\Core\Experiments\Manager as Experiments_Manager;
|
|
use Elementor\Core\Kits\Documents\Tabs\Settings_Page_Transitions;
|
|
use Elementor\Group_Control_Background;
|
|
use Elementor\Icons_Manager;
|
|
use Elementor\Utils;
|
|
use ElementorPro\Base\Module_Base;
|
|
use ElementorPro\Plugin;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly
|
|
}
|
|
|
|
class Module extends Module_Base {
|
|
|
|
// Module name.
|
|
const NAME = 'page-transitions';
|
|
|
|
// Loader types.
|
|
const TYPE_ANIMATION = 'animation';
|
|
const TYPE_ICON = 'icon';
|
|
const TYPE_IMAGE = 'image';
|
|
|
|
// Pre-loader types.
|
|
const LOADER_CIRCLE = 'circle';
|
|
const LOADER_CIRCLE_DASHED = 'circle-dashed';
|
|
const LOADER_BOUNCING_DOTS = 'bouncing-dots';
|
|
const LOADER_PULSING_DOTS = 'pulsing-dots';
|
|
const LOADER_PULSE = 'pulse';
|
|
const LOADER_OVERLAP = 'overlap';
|
|
const LOADER_SPINNERS = 'spinners';
|
|
const LOADER_NESTED_SPINNERS = 'nested-spinners';
|
|
const LOADER_OPPOSING_NESTED_SPINNERS = 'opposing-nested-spinners';
|
|
const LOADER_OPPOSING_NESTED_RINGS = 'opposing-nested-rings';
|
|
const LOADER_PROGRESS_BAR = 'progress-bar';
|
|
const LOADER_TWO_WAY_PROGRESS_BAR = 'two-way-progress-bar';
|
|
const LOADER_REPEATING_BAR = 'repeating-bar';
|
|
|
|
/**
|
|
* Module constructor.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct() {
|
|
// For cases where the user has an older Core version.
|
|
if ( ! class_exists( 'Elementor\Core\Kits\Documents\Tabs\Settings_Page_Transitions' ) ) {
|
|
return;
|
|
}
|
|
|
|
parent::__construct();
|
|
|
|
$this->add_actions();
|
|
}
|
|
|
|
/**
|
|
* Get the module name.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_name() {
|
|
return self::NAME;
|
|
}
|
|
|
|
/**
|
|
* Register the Page Transitions controls.
|
|
*
|
|
* @param $element Controls_Stack
|
|
* @param $section_id string
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register_controls( Controls_Stack $element, $section_id ) {
|
|
// Remove Page Transitions Banner (from Core version).
|
|
if ( 'section_page_transitions_teaser' !== $section_id ) {
|
|
return;
|
|
}
|
|
|
|
// Delete the Teaser message.
|
|
Plugin::elementor()->controls_manager->remove_control_from_stack(
|
|
$element->get_unique_name(),
|
|
[
|
|
'section_page_transitions_teaser',
|
|
'page_transitions_teaser',
|
|
]
|
|
);
|
|
|
|
// Replace the teaser message with actual controls.
|
|
$this->register_page_transitions_controls( $element );
|
|
}
|
|
|
|
/**
|
|
* Retrieve a control ID prefixed with the tab ID.
|
|
*
|
|
* @param string $id - Control id.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function get_control_id( $id ) {
|
|
$tab_id = Settings_Page_Transitions::TAB_ID;
|
|
$tab_id = str_replace( '-', '_', $tab_id );
|
|
|
|
return $tab_id . '_' . $id;
|
|
}
|
|
|
|
/**
|
|
* Add a Page Transitions preview button.
|
|
*
|
|
* @param Controls_Stack $controls_stack - Controls Stack context to add the button to.
|
|
* @param string $prefix - Button ID prefix.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function add_preview_button( $controls_stack, $prefix ) {
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( $prefix . '_play_button' ),
|
|
[
|
|
'type' => Controls_Manager::BUTTON,
|
|
'label_block' => true,
|
|
'text' => esc_html__( 'Preview Page Transition', 'elementor-pro' ),
|
|
'button_type' => 'default e-page-transition-preview',
|
|
'separator' => 'before',
|
|
'event' => 'elementorPageTransitions:animate',
|
|
'condition' => [
|
|
$this->get_control_id( 'entrance_animation' ) . '!' => '',
|
|
],
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Replace the Page Transition teaser with actual controls.
|
|
*
|
|
* @param Controls_Stack $controls_stack
|
|
*
|
|
* @return void
|
|
*/
|
|
public function register_page_transitions_controls( $controls_stack ) {
|
|
/**
|
|
* Page Transitions
|
|
*/
|
|
$controls_stack->start_controls_section(
|
|
'section_page_transitions',
|
|
[
|
|
'label' => esc_html__( 'Page Transitions', 'elementor-pro' ),
|
|
'tab' => Settings_Page_Transitions::TAB_ID,
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_group_control(
|
|
Group_Control_Background::get_type(),
|
|
[
|
|
'name' => $this->get_control_id( 'background' ),
|
|
'exclude' => [ 'image', 'video' ],
|
|
'fields_options' => [
|
|
'background' => [
|
|
'label' => esc_html__( 'Background', 'elementor-pro' ),
|
|
'default' => 'classic',
|
|
'description' => esc_html__( 'This is the page color behind your loading animation', 'elementor-pro' ),
|
|
],
|
|
'color' => [
|
|
'default' => '#FFBC7D',
|
|
],
|
|
],
|
|
'selector' => '{{WRAPPER}} e-page-transition',
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'entrance_animation' ),
|
|
[
|
|
'label' => esc_html__( 'Entrance Animation', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'label_block' => true,
|
|
// The animations are the opposite of what the user sees because the user thinks in the context
|
|
// of a page transition, while we actually animate the overlay.
|
|
'options' => [
|
|
'' => esc_html__( 'None', 'elementor-pro' ),
|
|
'fade-out' => esc_html__( 'Fade In', 'elementor-pro' ),
|
|
'fade-out-down' => esc_html__( 'Fade In Down', 'elementor-pro' ),
|
|
'fade-out-right' => esc_html__( 'Fade In Right', 'elementor-pro' ),
|
|
'fade-out-up' => esc_html__( 'Fade In Up', 'elementor-pro' ),
|
|
'fade-out-left' => esc_html__( 'Fade In Left', 'elementor-pro' ),
|
|
'zoom-out' => esc_html__( 'Zoom In', 'elementor-pro' ),
|
|
'slide-out-down' => esc_html__( 'Slide In Down', 'elementor-pro' ),
|
|
'slide-out-right' => esc_html__( 'Slide In Right', 'elementor-pro' ),
|
|
'slide-out-up' => esc_html__( 'Slide In Up', 'elementor-pro' ),
|
|
'slide-out-left' => esc_html__( 'Slide In Left', 'elementor-pro' ),
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-page-transition-entrance-animation: e-page-transition-{{VALUE}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'exit_animation' ),
|
|
[
|
|
'label' => esc_html__( 'Exit Animation', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'label_block' => true,
|
|
// The animations are the opposite of what the user sees because the user thinks in the context
|
|
// of a page transition, while we actually animate the overlay.
|
|
'options' => [
|
|
'' => esc_html__( 'None', 'elementor-pro' ),
|
|
'fade-in' => esc_html__( 'Fade Out', 'elementor-pro' ),
|
|
'fade-in-down' => esc_html__( 'Fade Out Down', 'elementor-pro' ),
|
|
'fade-in-right' => esc_html__( 'Fade Out Right', 'elementor-pro' ),
|
|
'fade-in-up' => esc_html__( 'Fade Out Up', 'elementor-pro' ),
|
|
'fade-in-left' => esc_html__( 'Fade Out Left', 'elementor-pro' ),
|
|
'zoom-in' => esc_html__( 'Zoom Out', 'elementor-pro' ),
|
|
'slide-in-down' => esc_html__( 'Slide Out Down', 'elementor-pro' ),
|
|
'slide-in-right' => esc_html__( 'Slide Out Right', 'elementor-pro' ),
|
|
'slide-in-up' => esc_html__( 'Slide Out Up', 'elementor-pro' ),
|
|
'slide-in-left' => esc_html__( 'Slide Out Left', 'elementor-pro' ),
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-page-transition-exit-animation: e-page-transition-{{VALUE}}',
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'entrance_animation' ) . '!' => '',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'animation_duration' ),
|
|
[
|
|
'label' => esc_html__( 'Animation Duration', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 's', 'ms', 'custom' ],
|
|
'default' => [
|
|
'unit' => 'ms',
|
|
'size' => 1500,
|
|
],
|
|
'range' => [
|
|
's' => [
|
|
'max' => 5,
|
|
],
|
|
'ms' => [
|
|
'max' => 5000,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'entrance_animation' ) . '!' => '',
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-page-transition-animation-duration: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$this->add_preview_button( $controls_stack, 'page_transition' );
|
|
|
|
$controls_stack->end_controls_section();
|
|
|
|
/**
|
|
* Preloader
|
|
*/
|
|
$controls_stack->start_controls_section(
|
|
'section_preloader',
|
|
[
|
|
'label' => esc_html__( 'Preloader', 'elementor-pro' ),
|
|
'tab' => Settings_Page_Transitions::TAB_ID,
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_type' ),
|
|
[
|
|
'label' => esc_html__( 'Type', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'options' => [
|
|
'' => esc_html__( 'None', 'elementor-pro' ),
|
|
self::TYPE_ANIMATION => esc_html__( 'Animation', 'elementor-pro' ),
|
|
self::TYPE_ICON => esc_html__( 'Icon', 'elementor-pro' ),
|
|
self::TYPE_IMAGE => esc_html__( 'Image', 'elementor-pro' ),
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_icon' ),
|
|
[
|
|
'label' => esc_html__( 'Icon', 'elementor-pro' ),
|
|
'type' => Controls_Manager::ICONS,
|
|
'fa4compatibility' => 'icon',
|
|
'default' => [
|
|
'value' => 'fas fa-spinner',
|
|
'library' => 'fa-solid',
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'icon',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_image' ),
|
|
[
|
|
'label' => esc_html__( 'Image', 'elementor-pro' ),
|
|
'type' => Controls_Manager::MEDIA,
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'image',
|
|
],
|
|
'dynamic' => [
|
|
'active' => true,
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_animation_type' ),
|
|
[
|
|
'label' => esc_html__( 'Animation', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'default' => self::LOADER_CIRCLE,
|
|
'options' => [
|
|
self::LOADER_CIRCLE => esc_html__( 'Circle', 'elementor-pro' ),
|
|
self::LOADER_CIRCLE_DASHED => esc_html__( 'Circle Dashed', 'elementor-pro' ),
|
|
self::LOADER_BOUNCING_DOTS => esc_html__( 'Bouncing Dots', 'elementor-pro' ),
|
|
self::LOADER_PULSING_DOTS => esc_html__( 'Pulsing Dots', 'elementor-pro' ),
|
|
self::LOADER_PULSE => esc_html__( 'Pulse', 'elementor-pro' ),
|
|
self::LOADER_OVERLAP => esc_html__( 'Overlap', 'elementor-pro' ),
|
|
self::LOADER_SPINNERS => esc_html__( 'Spinners', 'elementor-pro' ),
|
|
self::LOADER_NESTED_SPINNERS => esc_html__( 'Nested Spinners', 'elementor-pro' ),
|
|
self::LOADER_OPPOSING_NESTED_SPINNERS => esc_html__( 'Opposing Nested Spinners', 'elementor-pro' ),
|
|
self::LOADER_OPPOSING_NESTED_RINGS => esc_html__( 'Opposing Nested Rings', 'elementor-pro' ),
|
|
self::LOADER_PROGRESS_BAR => esc_html__( 'Progress Bar', 'elementor-pro' ),
|
|
self::LOADER_TWO_WAY_PROGRESS_BAR => esc_html__( 'Two Way Progress Bar', 'elementor-pro' ),
|
|
self::LOADER_REPEATING_BAR => esc_html__( 'Repeating Bar', 'elementor-pro' ),
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'animation',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_animation' ),
|
|
[
|
|
'label' => esc_html__( 'Animation', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SELECT,
|
|
'default' => '',
|
|
'options' => [
|
|
'' => esc_html__( 'None', 'elementor-pro' ),
|
|
'eicon-spin' => esc_html__( 'Spinning', 'elementor-pro' ),
|
|
'bounce' => esc_html__( 'Bounce', 'elementor-pro' ),
|
|
'flash' => esc_html__( 'Flash', 'elementor-pro' ),
|
|
'pulse' => esc_html__( 'Pulse', 'elementor-pro' ),
|
|
'rubberBand' => esc_html__( 'Rubber Band', 'elementor-pro' ),
|
|
'shake' => esc_html__( 'Shake', 'elementor-pro' ),
|
|
'headShake' => esc_html__( 'Head Shake', 'elementor-pro' ),
|
|
'swing' => esc_html__( 'Swing', 'elementor-pro' ),
|
|
'tada' => esc_html__( 'Tada', 'elementor-pro' ),
|
|
'wobble' => esc_html__( 'Wobble', 'elementor-pro' ),
|
|
'jello' => esc_html__( 'Jello', 'elementor-pro' ),
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => [ 'icon', 'image' ],
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-animation: {{VALUE}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
// Include animation speed control only for specific pre-loaders which support that.
|
|
$included_preloaders = [
|
|
self::LOADER_CIRCLE,
|
|
self::LOADER_CIRCLE_DASHED,
|
|
self::LOADER_BOUNCING_DOTS,
|
|
self::LOADER_PULSING_DOTS,
|
|
self::LOADER_SPINNERS,
|
|
self::LOADER_NESTED_SPINNERS,
|
|
self::LOADER_OPPOSING_NESTED_SPINNERS,
|
|
self::LOADER_OPPOSING_NESTED_RINGS,
|
|
self::LOADER_PROGRESS_BAR,
|
|
self::LOADER_TWO_WAY_PROGRESS_BAR,
|
|
self::LOADER_REPEATING_BAR,
|
|
];
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_animation_duration' ),
|
|
[
|
|
'label' => esc_html__( 'Animation Duration', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 's', 'ms', 'custom' ],
|
|
'default' => [
|
|
'unit' => 'ms',
|
|
'size' => 1500,
|
|
],
|
|
'range' => [
|
|
's' => [
|
|
'max' => 5,
|
|
],
|
|
'ms' => [
|
|
'max' => 5000,
|
|
],
|
|
],
|
|
// Show the control only for images, icons & specific custom pre-loaders.
|
|
'conditions' => [
|
|
'relation' => 'or',
|
|
'terms' => [
|
|
[
|
|
'name' => $this->get_control_id( 'preloader_type' ),
|
|
'operator' => 'in',
|
|
'value' => [
|
|
self::TYPE_IMAGE,
|
|
self::TYPE_ICON,
|
|
],
|
|
],
|
|
[
|
|
'relation' => 'and',
|
|
'terms' => [
|
|
[
|
|
'name' => $this->get_control_id( 'preloader_type' ),
|
|
'operator' => '=',
|
|
'value' => self::TYPE_ANIMATION,
|
|
],
|
|
[
|
|
'name' => $this->get_control_id( 'preloader_animation_type' ),
|
|
'operator' => 'in',
|
|
'value' => $included_preloaders,
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-animation-duration: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_delay' ),
|
|
[
|
|
'label' => esc_html__( 'Preloader Delay', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 's', 'ms', 'custom' ],
|
|
'default' => [
|
|
'unit' => 'ms',
|
|
'size' => 0,
|
|
],
|
|
'range' => [
|
|
's' => [
|
|
'max' => 5,
|
|
],
|
|
'ms' => [
|
|
'max' => 5000,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) . '!' => '',
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-delay: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'text_heading' ),
|
|
[
|
|
'label' => esc_html__( 'Style', 'elementor-pro' ),
|
|
'type' => Controls_Manager::HEADING,
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) . '!' => '',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_control(
|
|
$this->get_control_id( 'preloader_color' ),
|
|
[
|
|
'label' => esc_html__( 'Color', 'elementor-pro' ),
|
|
'type' => Controls_Manager::COLOR,
|
|
'default' => '#FFF',
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => [ 'icon', 'animation' ],
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-color: {{VALUE}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'preloader_size' ),
|
|
[
|
|
'label' => esc_html__( 'Size', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
|
|
'default' => [
|
|
'size' => 20,
|
|
],
|
|
'range' => [
|
|
'px' => [
|
|
'max' => 300,
|
|
],
|
|
'em' => [
|
|
'max' => 30,
|
|
],
|
|
'rem' => [
|
|
'max' => 30,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => [ 'icon', 'animation' ],
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-size: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
// Animation to exclude in rotation.
|
|
$excluded_animations = [
|
|
'eicon-spin',
|
|
'bounce',
|
|
'pulse',
|
|
'rubberBand',
|
|
'shake',
|
|
'headShake',
|
|
'swing',
|
|
'tada',
|
|
'wobble',
|
|
'jello',
|
|
];
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'preloader_rotate' ),
|
|
[
|
|
'label' => esc_html__( 'Rotate', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 'deg', 'grad', 'rad', 'turn' ],
|
|
'default' => [
|
|
'unit' => 'deg',
|
|
'size' => 0,
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'icon',
|
|
$this->get_control_id( 'preloader_animation' ) . '!' => $excluded_animations,
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-rotate: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'preloader_width' ),
|
|
[
|
|
'label' => esc_html__( 'Width', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
|
|
'default' => [
|
|
'unit' => '%',
|
|
],
|
|
'tablet_default' => [
|
|
'unit' => '%',
|
|
],
|
|
'mobile_default' => [
|
|
'unit' => '%',
|
|
],
|
|
'range' => [
|
|
'%' => [
|
|
'min' => 1,
|
|
'max' => 100,
|
|
],
|
|
'px' => [
|
|
'min' => 1,
|
|
'max' => 1000,
|
|
],
|
|
'em' => [
|
|
'max' => 100,
|
|
],
|
|
'rem' => [
|
|
'max' => 100,
|
|
],
|
|
'vw' => [
|
|
'min' => 1,
|
|
'max' => 100,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'image',
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-width: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'preloader_max_width' ),
|
|
[
|
|
'label' => esc_html__( 'Max Width', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
|
|
'default' => [
|
|
'unit' => '%',
|
|
],
|
|
'tablet_default' => [
|
|
'unit' => '%',
|
|
],
|
|
'mobile_default' => [
|
|
'unit' => '%',
|
|
],
|
|
'range' => [
|
|
'%' => [
|
|
'min' => 1,
|
|
'max' => 100,
|
|
],
|
|
'px' => [
|
|
'min' => 1,
|
|
'max' => 1000,
|
|
],
|
|
'em' => [
|
|
'max' => 100,
|
|
],
|
|
'rem' => [
|
|
'max' => 100,
|
|
],
|
|
'vw' => [
|
|
'min' => 1,
|
|
'max' => 100,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'image',
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-max-width: {{SIZE}}{{UNIT}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$controls_stack->add_responsive_control(
|
|
$this->get_control_id( 'preloader_opacity' ),
|
|
[
|
|
'label' => esc_html__( 'Opacity', 'elementor-pro' ),
|
|
'type' => Controls_Manager::SLIDER,
|
|
'range' => [
|
|
'px' => [
|
|
'min' => 0,
|
|
'max' => 1,
|
|
'step' => 0.1,
|
|
],
|
|
],
|
|
'condition' => [
|
|
$this->get_control_id( 'preloader_type' ) => 'image',
|
|
],
|
|
'selectors' => [
|
|
'{{WRAPPER}}' => '--e-preloader-opacity: {{SIZE}}',
|
|
],
|
|
]
|
|
);
|
|
|
|
$this->add_preview_button( $controls_stack, 'preloader' );
|
|
|
|
$controls_stack->end_controls_section();
|
|
}
|
|
|
|
/**
|
|
* Get a control value from the settings.
|
|
*
|
|
* @param string $control - Non prefixed control name.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
private function get_setting( $control ) {
|
|
$document = Plugin::elementor()->kits_manager->get_active_kit_for_frontend();
|
|
$control = $this->get_control_id( $control );
|
|
|
|
return $document->get_settings_for_display( $control );
|
|
}
|
|
|
|
/**
|
|
* Get the Page Transitions element CSS class.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function get_page_transition_class() {
|
|
$is_preview_mode = Plugin::elementor()->preview->is_preview_mode();
|
|
return $is_preview_mode ? 'e-page-transition--entered' : 'e-page-transition--entering';
|
|
}
|
|
|
|
/**
|
|
* Get the Page Transitions links Regex filter.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function get_page_transition_filter() {
|
|
// Prepare the admin URL to be "regex-ready" (escape special characters).
|
|
$admin_url = preg_quote( get_admin_url(), '/' );
|
|
|
|
// A regex pattern for URLs under `wp-admin`.
|
|
return '^' . $admin_url;
|
|
}
|
|
|
|
/**
|
|
* Print the Page Transition element attributes.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function print_render_attribute_string() {
|
|
$kit = Plugin::elementor()->kits_manager->get_active_kit();
|
|
|
|
$settings = [
|
|
'preloader_type',
|
|
'preloader_icon',
|
|
'preloader_image',
|
|
'preloader_animation_type',
|
|
];
|
|
|
|
foreach ( $settings as $setting ) {
|
|
$key = str_replace( '_', '-', $setting );
|
|
$value = $this->get_setting( $setting );
|
|
|
|
if ( empty( $value ) ) {
|
|
continue;
|
|
}
|
|
|
|
// Change the key & value specifically for the image control, since the returned value
|
|
// is an array while the Page Transition element expects a URL as a string.
|
|
if ( 'preloader-image' === $key ) {
|
|
$key = 'preloader-image-url';
|
|
$value = $value['url'];
|
|
}
|
|
|
|
$kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, $key, $value );
|
|
}
|
|
|
|
$class = $this->get_page_transition_class();
|
|
|
|
if ( $class ) {
|
|
$kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, 'class', $class );
|
|
}
|
|
|
|
// Add URL regex filter to filter only URLs without `wp-admin`.
|
|
$kit->add_render_attribute( Settings_Page_Transitions::TAB_ID, 'exclude', $this->get_page_transition_filter() );
|
|
|
|
$kit->print_render_attribute_string( Settings_Page_Transitions::TAB_ID );
|
|
}
|
|
|
|
/**
|
|
* Determine if the Page Transition element should be rendered.
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function should_render() {
|
|
// Don't render the Page Transition if the page is a non-interactive (static-rendered) page (e.g. template-preview).
|
|
if ( Plugin::elementor()->frontend->is_static_render_mode() ) {
|
|
return false;
|
|
}
|
|
|
|
$has_entrance_animation = ! ! $this->get_setting( 'entrance_animation' );
|
|
$has_preloader = ! ! $this->get_setting( 'preloader_type' );
|
|
$is_page = ( is_singular() || is_archive() ) && ! is_paged();
|
|
|
|
return $is_page && ( $has_entrance_animation || $has_preloader );
|
|
}
|
|
|
|
/**
|
|
* Whether the Page Transitions scripts should be enqueued.
|
|
* When in preview mode, the scripts should be loaded since the user might not have a Page Transition
|
|
* set on initial load but he will need them when changing the settings.
|
|
*
|
|
* @return bool
|
|
*/
|
|
private function should_enqueue_scripts() {
|
|
return $this->should_render() || Plugin::elementor()->preview->is_preview_mode();
|
|
}
|
|
|
|
/**
|
|
* Render the Page Transition markup.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function render() {
|
|
$is_inline_font_icon_active = Plugin::elementor()->experiments->is_feature_active( 'e_font_icon_svg' );
|
|
|
|
?>
|
|
<e-page-transition <?php $this->print_render_attribute_string(); ?>>
|
|
<?php
|
|
$icon = $this->get_setting( 'preloader_icon' );
|
|
|
|
// Render inline SVG icon when the experiment is active, since the component itself
|
|
// shouldn't know about the Editor or the experiments.
|
|
if ( $is_inline_font_icon_active && ! empty( $icon ) ) {
|
|
Icons_Manager::render_icon( $icon, [ 'class' => 'e-page-transition--preloader' ] );
|
|
}
|
|
?>
|
|
</e-page-transition>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Load `instant-page` library for better performance.
|
|
*
|
|
* Ref: https://instant.page/
|
|
*
|
|
* @return void
|
|
*/
|
|
private function enqueue_instant_page_script() {
|
|
$suffix = Utils::is_script_debug() ? '' : '.min';
|
|
|
|
wp_enqueue_script(
|
|
'instant-page',
|
|
ELEMENTOR_PRO_ASSETS_URL . "/lib/instant-page/instant-page{$suffix}.js",
|
|
null,
|
|
ELEMENTOR_PRO_VERSION,
|
|
true
|
|
);
|
|
|
|
// Load instant-page as module.
|
|
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
|
|
if ( 'instant-page' === $handle ) {
|
|
$tag = str_replace( 'text/javascript', 'module', $tag );
|
|
}
|
|
return $tag;
|
|
}, 10, 2 );
|
|
}
|
|
|
|
/**
|
|
* Enqueue frontend scripts.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function enqueue_scripts() {
|
|
$this->enqueue_instant_page_script();
|
|
|
|
wp_enqueue_script(
|
|
'page-transitions',
|
|
$this->get_js_assets_url( 'page-transitions' ),
|
|
null,
|
|
ELEMENTOR_PRO_VERSION,
|
|
false
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get the base URL for assets.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function get_assets_base_url() {
|
|
return ELEMENTOR_PRO_URL;
|
|
}
|
|
|
|
/**
|
|
* Add actions & filters.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function add_actions() {
|
|
add_action( 'elementor/element/after_section_end', [ $this, 'register_controls' ], 10, 2 );
|
|
|
|
add_action( 'wp_enqueue_scripts', function () {
|
|
if ( $this->should_enqueue_scripts() ) {
|
|
$this->enqueue_scripts();
|
|
}
|
|
} );
|
|
|
|
// Render the Page Transition element after the body open tag.
|
|
add_action( 'wp_body_open', function () {
|
|
if ( $this->should_render() ) {
|
|
$this->render();
|
|
}
|
|
}, 10, 2 );
|
|
}
|
|
}
|