PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.81
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.81
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / features / Floating_Animation / Floating_Animation.php

Floating_Animation.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.81, at includes/features/Floating_Animation/Floating_Animation.php

202 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php /** @noinspection SpellCheckingInspection, PhpUnused */
2
3 namespace King_Addons;
4
5 use Elementor\Controls_Manager;
6 use Elementor\Element_Base;
7
8 if (!defined('ABSPATH')) {
9 exit; // Exit if accessed directly.
10 }
11
12 class Floating_Animation
13 {
14 private static ?Floating_Animation $_instance = null;
15
16 public static function instance(): Floating_Animation
17 {
18 if (is_null(self::$_instance)) {
19 self::$_instance = new self();
20 }
21 return self::$_instance;
22 }
23
24 /** @noinspection DuplicatedCode */
25 public function __construct()
26 {
27 add_action('elementor/element/container/section_layout/after_section_end', [__CLASS__, 'addControls'], 1);
28 add_action('elementor/element/column/section_advanced/after_section_end', [__CLASS__, 'addControls'], 1);
29 add_action('elementor/element/section/section_advanced/after_section_end', [__CLASS__, 'addControls'], 1);
30 add_action('elementor/element/common/_section_style/after_section_end', [__CLASS__, 'addControls'], 1);
31 add_action('elementor/preview/enqueue_scripts', [__CLASS__, 'enqueueScripts'], 1);
32 add_action('elementor/frontend/before_render', [__CLASS__, 'renderAnimation'], 1);
33 }
34
35 public static function enqueueScripts(): void
36 {
37 if (!wp_script_is(KING_ADDONS_ASSETS_UNIQUE_KEY . '-' . 'floating-animation' . '-' . 'preview-handler')) {
38 wp_enqueue_script(KING_ADDONS_ASSETS_UNIQUE_KEY . '-' . 'floating-animation' . '-' . 'preview-handler', '', array('jquery'), KING_ADDONS_VERSION);
39 }
40 }
41
42 public static function addControls(Element_Base $element): void
43 {
44 $element->start_controls_section(
45 'kng_floating_animation_section',
46 [
47 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Floating Animation', 'king-addons'),
48 'tab' => Controls_Manager::TAB_ADVANCED
49 ]
50 );
51
52 $element->add_control(
53 'kng_floating_animation_switch',
54 [
55 'label' => esc_html__('Enable Floating Animation', 'king-addons'),
56 'type' => Controls_Manager::SWITCHER,
57 'prefix_class' => 'kng-floating-animation-',
58 'frontend_available' => true
59 ]
60 );
61
62 $element->add_control(
63 'kng_floating_animation_value_X',
64 [
65 'label' => esc_html__('Offset X', 'king-addons'),
66 'type' => Controls_Manager::NUMBER,
67 'frontend_available' => true,
68 'step' => 1,
69 'default' => 0,
70 'condition' => [
71 'kng_floating_animation_switch!' => ''
72 ]
73 ]
74 );
75
76 $element->add_control(
77 'kng_floating_animation_value',
78 [
79 'label' => esc_html__('Offset Y', 'king-addons'),
80 'type' => Controls_Manager::NUMBER,
81 'frontend_available' => true,
82 'step' => 1,
83 'default' => -20,
84 'condition' => [
85 'kng_floating_animation_switch!' => ''
86 ]
87 ]
88 );
89
90 $element->add_control(
91 'kng_floating_animation_duration',
92 [
93 'label' => esc_html__('Duration', 'king-addons') . ' (ms)',
94 'type' => Controls_Manager::NUMBER,
95 'frontend_available' => true,
96 'min' => 0,
97 'step' => 1,
98 'default' => 6000,
99 'condition' => [
100 'kng_floating_animation_switch!' => ''
101 ]
102 ]
103 );
104
105 $element->add_control(
106 'kng_floating_animation_delay',
107 [
108 'label' => esc_html__('Animation delay', 'king-addons') . ' (ms)',
109 'type' => Controls_Manager::NUMBER,
110 'frontend_available' => true,
111 'min' => 0,
112 'step' => 1,
113 'default' => 0,
114 'condition' => [
115 'kng_floating_animation_switch!' => ''
116 ]
117 ]
118 );
119
120 $element->end_controls_section();
121 }
122
123 /**
124 * Renders the inline CSS for the floating animation if enabled.
125 * This function is hooked into 'elementor/frontend/before_render'.
126 * It prints a <style> tag directly into the HTML output.
127 *
128 * @param Element_Base $element The current Elementor element object.
129 */
130 public static function renderAnimation(Element_Base $element): void
131 {
132 $settings = $element->get_settings_for_display();
133 $element_id = $element->get_id(); // Get element ID once for efficiency
134
135 // 1. CHECK THE SWITCHER CONTROL
136 // Elementor's switcher control typically uses 'yes' for the enabled state.
137 if (empty($settings['kng_floating_animation_switch']) || 'yes' !== $settings['kng_floating_animation_switch']) {
138 return; // Animation is disabled for this element, do nothing.
139 }
140
141 // 2. GET ANIMATION VALUES FROM SETTINGS
142 // Use null coalescing operator (??) to provide default values if settings are not set.
143 $value_x = $settings['kng_floating_animation_value_X'] ?? 0;
144 $value_y = $settings['kng_floating_animation_value'] ?? 0; // Using your specific setting key name for Y
145 $duration = $settings['kng_floating_animation_duration'] ?? null; // Get duration, check validity later
146 $delay = $settings['kng_floating_animation_delay'] ?? 0;
147
148 // 3. VALIDATE IF ANIMATION IS MEANINGFUL
149 // Animation requires a duration greater than 0ms to be visible.
150 if (empty($duration) || intval($duration) <= 0) {
151 // If duration is not set or is zero/negative, don't output the style tag.
152 return;
153 }
154
155 // 4. SANITIZE NUMERIC VALUES
156 // Use intval for values that can be negative (translate offsets).
157 // Use absint for values that must be non-negative (duration, delay).
158 // This prevents invalid CSS and potential security issues if settings were compromised.
159 $value_x_sanitized = intval($value_x);
160 $value_y_sanitized = intval($value_y);
161 $duration_sanitized = absint($duration);
162 $delay_sanitized = absint($delay);
163
164 // 5. GENERATE THE CSS STRING
165 // Use the element ID directly in animation names and selectors (Elementor IDs are safe).
166 // Use sprintf for cleaner code when building strings with variables.
167 $animation_name = 'floating-animation-' . $element_id;
168 $selector = '.elementor-element-' . $element_id;
169
170 $css = sprintf(
171 // Use a unique ID for the style tag itself, based on the element ID.
172 // Use esc_attr() for sanitizing the ID attribute value.
173 '<style id="floating-anim-%1$s">
174 @keyframes %2$s {
175 0%% { transform: translate(0, 0); }
176 50%% { transform: translate(%3$dpx, %4$dpx); }
177 100%% { transform: translate(0, 0); }
178 }
179 %5$s {
180 animation-name: %2$s;
181 animation-duration: %6$dms;
182 animation-timing-function: ease-in-out;
183 animation-iteration-count: infinite;
184 animation-delay: %7$dms;
185 }
186 </style>',
187 esc_attr($element_id), // %1$s: Sanitized ID for the <style> tag attribute
188 $animation_name, // %2$s: Animation name (uses safe element ID)
189 $value_x_sanitized, // %3$s: Sanitized X offset (integer)
190 $value_y_sanitized, // %4$s: Sanitized Y offset (integer)
191 $selector, // %5$s: Element selector (uses safe element ID)
192 $duration_sanitized, // %6$s: Sanitized duration (non-negative integer)
193 $delay_sanitized // %7$s: Sanitized delay (non-negative integer)
194 );
195
196 // 6. OUTPUT THE GENERATED CSS
197 // Since this function is called within the 'elementor/frontend/before_render' hook,
198 // using print or echo will directly insert the <style> tag into the page's HTML
199 // just before the element's own HTML is rendered.
200 print $css;
201 }
202 }