PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.83
51.1.84 51.1.85 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 All 39 releases
← All changes | includes/features/Floating_Animation/Floating_Animation.php +202 -0 51.1.251.1.83 View file →
@@ -1,0 +1,202 @@
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 +}