PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.49
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.49
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 / widgets / Magnetic_Buttons / Magnetic_Buttons.php

Magnetic_Buttons.php in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.49, at includes/widgets/Magnetic_Buttons/Magnetic_Buttons.php

780 lines 23.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Magnetic Buttons Widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Box_Shadow;
12 use Elementor\Group_Control_Typography;
13 use Elementor\Icons_Manager;
14 use Elementor\Widget_Base;
15
16 if (!defined('ABSPATH')) {
17 exit;
18 }
19
20 /**
21 * Magnetic button widget.
22 */
23 class Magnetic_Buttons extends Widget_Base
24 {
25 /**
26 * Widget slug.
27 *
28 * @return string
29 */
30 public function get_name(): string
31 {
32 return 'king-addons-magnetic-buttons';
33 }
34
35 /**
36 * Widget title.
37 *
38 * @return string
39 */
40 public function get_title(): string
41 {
42 return esc_html__('Magnetic Buttons', 'king-addons');
43 }
44
45 /**
46 * Widget icon.
47 *
48 * @return string
49 */
50 public function get_icon(): string
51 {
52 return 'king-addons-icon king-addons-magnetic-buttons';
53 }
54
55 /**
56 * Style dependencies.
57 *
58 * @return array<int, string>
59 */
60 public function get_style_depends(): array
61 {
62 return [
63 KING_ADDONS_ASSETS_UNIQUE_KEY . '-magnetic-buttons-style',
64 'elementor-icons-fa-solid',
65 'elementor-icons-fa-regular',
66 'elementor-icons-fa-brands',
67 ];
68 }
69
70 /**
71 * Script dependencies.
72 *
73 * @return array<int, string>
74 */
75 public function get_script_depends(): array
76 {
77 return [
78 KING_ADDONS_ASSETS_UNIQUE_KEY . '-magnetic-buttons-script',
79 ];
80 }
81
82 /**
83 * Categories.
84 *
85 * @return array<int, string>
86 */
87 public function get_categories(): array
88 {
89 return ['king-addons'];
90 }
91
92 /**
93 * Keywords.
94 *
95 * @return array<int, string>
96 */
97 public function get_keywords(): array
98 {
99 return ['magnetic', 'button', 'cta', 'hover', 'interactive'];
100 }
101
102 /**
103 * Register controls.
104 *
105 * @return void
106 */
107 public function register_controls(): void
108 {
109 $this->register_content_controls();
110 $this->register_magnet_controls();
111 $this->register_style_controls();
112 $this->register_pro_notice_controls();
113 }
114
115 /**
116 * Render widget output.
117 *
118 * @return void
119 */
120 public function render(): void
121 {
122 $settings = $this->get_settings_for_display();
123
124 $button_text = trim((string) ($settings['kng_button_text'] ?? ''));
125 $link = $settings['kng_button_link'] ?? [];
126 $href = is_array($link) ? ($link['url'] ?? '') : '';
127 $is_external = is_array($link) && !empty($link['is_external']);
128 $nofollow = is_array($link) && !empty($link['nofollow']);
129
130 $rels = [];
131 if ($is_external) {
132 $rels[] = 'noopener';
133 $rels[] = 'noreferrer';
134 }
135 if ($nofollow) {
136 $rels[] = 'nofollow';
137 }
138 $rel_attr = !empty($rels) ? ' rel="' . esc_attr(implode(' ', array_unique($rels))) . '"' : '';
139 $target_attr = $is_external ? ' target="_blank"' : '';
140
141 $size = $this->sanitize_size($settings['kng_button_size'] ?? 'medium');
142 $icon_enabled = ($settings['kng_button_icon_enable'] ?? '') === 'yes';
143 $icon_position = $this->sanitize_icon_position($settings['kng_button_icon_position'] ?? 'left');
144
145 $options = $this->get_magnet_options($settings);
146
147 $wrapper_classes = [
148 'king-addons-magnetic-buttons',
149 'king-addons-magnetic-buttons--size-' . $size,
150 ];
151
152 $this->add_render_attribute('wrapper', [
153 'class' => $wrapper_classes,
154 'data-options' => wp_json_encode($options),
155 'data-target' => 'button',
156 ]);
157
158 $button_classes = ['king-addons-magnetic-buttons__button'];
159 if ($icon_enabled && 'right' === $icon_position) {
160 $button_classes[] = 'is-icon-right';
161 }
162
163 $this->add_render_attribute('button', 'class', $button_classes);
164 if ('' === $button_text) {
165 $aria_label = sanitize_text_field($settings['kng_button_aria_label'] ?? '');
166 if ('' === $aria_label) {
167 $aria_label = esc_html__('Magnetic Button', 'king-addons');
168 }
169 $this->add_render_attribute('button', 'aria-label', $aria_label);
170 }
171
172 echo '<div ' . $this->get_render_attribute_string('wrapper') . '>';
173 echo '<div class="king-addons-magnetic-buttons__wrap">';
174
175 if (!empty($href)) {
176 echo '<a ' . $this->get_render_attribute_string('button') . ' href="' . esc_url($href) . '"' . $target_attr . $rel_attr . '>';
177 } else {
178 echo '<button ' . $this->get_render_attribute_string('button') . ' type="button">';
179 }
180
181 echo '<span class="king-addons-magnetic-buttons__content">';
182
183 if ($icon_enabled && !empty($settings['kng_button_icon']['value'])) {
184 echo '<span class="king-addons-magnetic-buttons__icon" aria-hidden="true">';
185 Icons_Manager::render_icon($settings['kng_button_icon'], ['aria-hidden' => 'true']);
186 echo '</span>';
187 }
188
189 if (!empty($button_text)) {
190 echo '<span class="king-addons-magnetic-buttons__text">' . esc_html($button_text) . '</span>';
191 }
192
193 echo '</span>';
194
195 if (!empty($href)) {
196 echo '</a>';
197 } else {
198 echo '</button>';
199 }
200
201 echo '</div>';
202 echo '</div>';
203 }
204
205 /**
206 * Content controls.
207 *
208 * @return void
209 */
210 protected function register_content_controls(): void
211 {
212 $this->start_controls_section(
213 'kng_content_section',
214 [
215 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
216 'tab' => Controls_Manager::TAB_CONTENT,
217 ]
218 );
219
220 $this->add_control(
221 'kng_button_text',
222 [
223 'label' => esc_html__('Button Text', 'king-addons'),
224 'type' => Controls_Manager::TEXT,
225 'dynamic' => [
226 'active' => true,
227 ],
228 'default' => esc_html__('Magnetic Button', 'king-addons'),
229 'label_block' => true,
230 ]
231 );
232
233 $this->add_control(
234 'kng_button_aria_label',
235 [
236 'label' => esc_html__('Aria Label', 'king-addons'),
237 'type' => Controls_Manager::TEXT,
238 'dynamic' => [
239 'active' => true,
240 ],
241 'label_block' => true,
242 'description' => esc_html__('Used when the button text is empty.', 'king-addons'),
243 ]
244 );
245
246 $this->add_control(
247 'kng_button_link',
248 [
249 'label' => esc_html__('Button Link', 'king-addons'),
250 'type' => Controls_Manager::URL,
251 'dynamic' => [
252 'active' => true,
253 ],
254 'placeholder' => esc_html__('https://', 'king-addons'),
255 ]
256 );
257
258 $this->add_responsive_control(
259 'kng_button_alignment',
260 [
261 'label' => esc_html__('Alignment', 'king-addons'),
262 'type' => Controls_Manager::CHOOSE,
263 'toggle' => true,
264 'default' => 'left',
265 'options' => [
266 'left' => [
267 'title' => esc_html__('Left', 'king-addons'),
268 'icon' => 'eicon-text-align-left',
269 ],
270 'center' => [
271 'title' => esc_html__('Center', 'king-addons'),
272 'icon' => 'eicon-text-align-center',
273 ],
274 'right' => [
275 'title' => esc_html__('Right', 'king-addons'),
276 'icon' => 'eicon-text-align-right',
277 ],
278 ],
279 'selectors' => [
280 '{{WRAPPER}} .king-addons-magnetic-buttons' => 'text-align: {{VALUE}};',
281 ],
282 ]
283 );
284
285 $this->add_control(
286 'kng_button_size',
287 [
288 'label' => esc_html__('Size', 'king-addons'),
289 'type' => Controls_Manager::SELECT,
290 'default' => 'medium',
291 'options' => [
292 'small' => esc_html__('Small', 'king-addons'),
293 'medium' => esc_html__('Medium', 'king-addons'),
294 'large' => esc_html__('Large', 'king-addons'),
295 ],
296 ]
297 );
298
299 $this->add_control(
300 'kng_button_icon_enable',
301 [
302 'label' => esc_html__('Enable Icon', 'king-addons'),
303 'type' => Controls_Manager::SWITCHER,
304 'return_value' => 'yes',
305 'default' => '',
306 'separator' => 'before',
307 ]
308 );
309
310 $this->add_control(
311 'kng_button_icon',
312 [
313 'label' => esc_html__('Icon', 'king-addons'),
314 'type' => Controls_Manager::ICONS,
315 'default' => [
316 'value' => 'fas fa-arrow-right',
317 'library' => 'fa-solid',
318 ],
319 'condition' => [
320 'kng_button_icon_enable' => 'yes',
321 ],
322 ]
323 );
324
325 $this->add_control(
326 'kng_button_icon_position',
327 [
328 'label' => esc_html__('Icon Position', 'king-addons'),
329 'type' => Controls_Manager::SELECT,
330 'default' => 'left',
331 'options' => [
332 'left' => esc_html__('Left', 'king-addons'),
333 'right' => esc_html__('Right', 'king-addons'),
334 ],
335 'condition' => [
336 'kng_button_icon_enable' => 'yes',
337 ],
338 ]
339 );
340
341 $this->add_responsive_control(
342 'kng_button_icon_spacing',
343 [
344 'label' => esc_html__('Icon Spacing', 'king-addons'),
345 'type' => Controls_Manager::SLIDER,
346 'size_units' => ['px', 'em'],
347 'range' => [
348 'px' => [
349 'min' => 0,
350 'max' => 40,
351 ],
352 'em' => [
353 'min' => 0,
354 'max' => 4,
355 ],
356 ],
357 'selectors' => [
358 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-icon-gap: {{SIZE}}{{UNIT}};',
359 ],
360 'condition' => [
361 'kng_button_icon_enable' => 'yes',
362 ],
363 ]
364 );
365
366 $this->end_controls_section();
367 }
368
369 /**
370 * Magnetic controls.
371 *
372 * @return void
373 */
374 protected function register_magnet_controls(): void
375 {
376 $this->start_controls_section(
377 'kng_magnet_section',
378 [
379 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Magnetic', 'king-addons'),
380 'tab' => Controls_Manager::TAB_CONTENT,
381 ]
382 );
383
384 $this->add_control(
385 'kng_magnet_enable',
386 [
387 'label' => esc_html__('Enable Magnet', 'king-addons'),
388 'type' => Controls_Manager::SWITCHER,
389 'return_value' => 'yes',
390 'default' => 'yes',
391 ]
392 );
393
394 $this->add_control(
395 'kng_magnet_strength',
396 [
397 'label' => esc_html__('Strength', 'king-addons'),
398 'type' => Controls_Manager::SLIDER,
399 'size_units' => ['px'],
400 'range' => [
401 'px' => [
402 'min' => 0,
403 'max' => 100,
404 ],
405 ],
406 'default' => [
407 'size' => 25,
408 'unit' => 'px',
409 ],
410 'condition' => [
411 'kng_magnet_enable' => 'yes',
412 ],
413 ]
414 );
415
416 $this->add_control(
417 'kng_magnet_radius',
418 [
419 'label' => esc_html__('Radius', 'king-addons'),
420 'type' => Controls_Manager::SLIDER,
421 'size_units' => ['px'],
422 'range' => [
423 'px' => [
424 'min' => 20,
425 'max' => 400,
426 ],
427 ],
428 'default' => [
429 'size' => 120,
430 'unit' => 'px',
431 ],
432 'condition' => [
433 'kng_magnet_enable' => 'yes',
434 ],
435 ]
436 );
437
438 $this->add_control(
439 'kng_magnet_max_offset',
440 [
441 'label' => esc_html__('Max Offset', 'king-addons'),
442 'type' => Controls_Manager::SLIDER,
443 'size_units' => ['px'],
444 'range' => [
445 'px' => [
446 'min' => 0,
447 'max' => 60,
448 ],
449 ],
450 'default' => [
451 'size' => 12,
452 'unit' => 'px',
453 ],
454 'condition' => [
455 'kng_magnet_enable' => 'yes',
456 ],
457 ]
458 );
459
460 $this->add_control(
461 'kng_magnet_return_speed',
462 [
463 'label' => esc_html__('Return Speed', 'king-addons'),
464 'type' => Controls_Manager::SLIDER,
465 'size_units' => ['px'],
466 'range' => [
467 'px' => [
468 'min' => 0,
469 'max' => 100,
470 ],
471 ],
472 'default' => [
473 'size' => 40,
474 'unit' => 'px',
475 ],
476 'condition' => [
477 'kng_magnet_enable' => 'yes',
478 ],
479 ]
480 );
481
482 $this->add_control(
483 'kng_magnet_easing',
484 [
485 'label' => esc_html__('Easing', 'king-addons'),
486 'type' => Controls_Manager::SELECT,
487 'default' => 'smooth',
488 'options' => [
489 'smooth' => esc_html__('Smooth', 'king-addons'),
490 'snappy' => esc_html__('Snappy', 'king-addons'),
491 'calm' => esc_html__('Calm', 'king-addons'),
492 ],
493 'condition' => [
494 'kng_magnet_enable' => 'yes',
495 ],
496 ]
497 );
498
499 $this->end_controls_section();
500 }
501
502 /**
503 * Style controls.
504 *
505 * @return void
506 */
507 protected function register_style_controls(): void
508 {
509 $this->start_controls_section(
510 'kng_style_button_section',
511 [
512 'label' => esc_html__('Button', 'king-addons'),
513 'tab' => Controls_Manager::TAB_STYLE,
514 ]
515 );
516
517 $this->add_group_control(
518 Group_Control_Typography::get_type(),
519 [
520 'name' => 'kng_button_typography',
521 'selector' => '{{WRAPPER}} .king-addons-magnetic-buttons__button',
522 ]
523 );
524
525 $this->add_responsive_control(
526 'kng_button_padding',
527 [
528 'label' => esc_html__('Padding', 'king-addons'),
529 'type' => Controls_Manager::DIMENSIONS,
530 'size_units' => ['px', 'em', '%'],
531 'selectors' => [
532 '{{WRAPPER}} .king-addons-magnetic-buttons__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
533 ],
534 ]
535 );
536
537 $this->add_responsive_control(
538 'kng_button_radius',
539 [
540 'label' => esc_html__('Border Radius', 'king-addons'),
541 'type' => Controls_Manager::SLIDER,
542 'size_units' => ['px', '%'],
543 'range' => [
544 'px' => [
545 'min' => 0,
546 'max' => 80,
547 ],
548 '%' => [
549 'min' => 0,
550 'max' => 50,
551 ],
552 ],
553 'selectors' => [
554 '{{WRAPPER}} .king-addons-magnetic-buttons__button' => 'border-radius: {{SIZE}}{{UNIT}};',
555 ],
556 ]
557 );
558
559 $this->add_responsive_control(
560 'kng_button_border_width',
561 [
562 'label' => esc_html__('Border Width', 'king-addons'),
563 'type' => Controls_Manager::SLIDER,
564 'size_units' => ['px'],
565 'range' => [
566 'px' => [
567 'min' => 0,
568 'max' => 8,
569 ],
570 ],
571 'selectors' => [
572 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-border-width: {{SIZE}}{{UNIT}};',
573 ],
574 ]
575 );
576
577 $this->add_control(
578 'kng_button_border_style',
579 [
580 'label' => esc_html__('Border Style', 'king-addons'),
581 'type' => Controls_Manager::SELECT,
582 'default' => 'solid',
583 'options' => [
584 'none' => esc_html__('None', 'king-addons'),
585 'solid' => esc_html__('Solid', 'king-addons'),
586 'dashed' => esc_html__('Dashed', 'king-addons'),
587 'dotted' => esc_html__('Dotted', 'king-addons'),
588 'double' => esc_html__('Double', 'king-addons'),
589 ],
590 'selectors' => [
591 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-border-style: {{VALUE}};',
592 ],
593 ]
594 );
595
596 $this->start_controls_tabs('kng_button_style_tabs');
597
598 $this->start_controls_tab(
599 'kng_button_style_tab_normal',
600 [
601 'label' => esc_html__('Normal', 'king-addons'),
602 ]
603 );
604
605 $this->add_control(
606 'kng_button_background',
607 [
608 'label' => esc_html__('Background Color', 'king-addons'),
609 'type' => Controls_Manager::COLOR,
610 'selectors' => [
611 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-bg: {{VALUE}};',
612 ],
613 ]
614 );
615
616 $this->add_control(
617 'kng_button_text_color',
618 [
619 'label' => esc_html__('Text Color', 'king-addons'),
620 'type' => Controls_Manager::COLOR,
621 'selectors' => [
622 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-color: {{VALUE}};',
623 ],
624 ]
625 );
626
627 $this->add_control(
628 'kng_button_border_color',
629 [
630 'label' => esc_html__('Border Color', 'king-addons'),
631 'type' => Controls_Manager::COLOR,
632 'selectors' => [
633 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-border: {{VALUE}};',
634 ],
635 ]
636 );
637
638 $this->add_group_control(
639 Group_Control_Box_Shadow::get_type(),
640 [
641 'name' => 'kng_button_shadow',
642 'selector' => '{{WRAPPER}} .king-addons-magnetic-buttons__button',
643 ]
644 );
645
646 $this->end_controls_tab();
647
648 $this->start_controls_tab(
649 'kng_button_style_tab_hover',
650 [
651 'label' => esc_html__('Hover', 'king-addons'),
652 ]
653 );
654
655 $this->add_control(
656 'kng_button_background_hover',
657 [
658 'label' => esc_html__('Background Color', 'king-addons'),
659 'type' => Controls_Manager::COLOR,
660 'selectors' => [
661 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-bg-hover: {{VALUE}};',
662 ],
663 ]
664 );
665
666 $this->add_control(
667 'kng_button_text_color_hover',
668 [
669 'label' => esc_html__('Text Color', 'king-addons'),
670 'type' => Controls_Manager::COLOR,
671 'selectors' => [
672 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-color-hover: {{VALUE}};',
673 ],
674 ]
675 );
676
677 $this->add_control(
678 'kng_button_border_color_hover',
679 [
680 'label' => esc_html__('Border Color', 'king-addons'),
681 'type' => Controls_Manager::COLOR,
682 'selectors' => [
683 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-border-hover: {{VALUE}};',
684 ],
685 ]
686 );
687
688 $this->add_group_control(
689 Group_Control_Box_Shadow::get_type(),
690 [
691 'name' => 'kng_button_shadow_hover',
692 'selector' => '{{WRAPPER}} .king-addons-magnetic-buttons__button:hover',
693 ]
694 );
695
696 $this->end_controls_tab();
697
698 $this->end_controls_tabs();
699
700 $this->add_control(
701 'kng_button_transition',
702 [
703 'label' => esc_html__('Transition Duration (ms)', 'king-addons'),
704 'type' => Controls_Manager::NUMBER,
705 'default' => 220,
706 'min' => 0,
707 'step' => 10,
708 'selectors' => [
709 '{{WRAPPER}} .king-addons-magnetic-buttons' => '--ka-magnetic-button-transition: {{VALUE}}ms;',
710 ],
711 ]
712 );
713
714 $this->end_controls_section();
715 }
716
717 /**
718 * Register Pro notice controls.
719 *
720 * @return void
721 */
722 public function register_pro_notice_controls(): void
723 {
724 if (!king_addons_can_use_pro()) {
725 Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'magnetic-buttons', [
726 'Card and icon magnet modes',
727 'Boundary constraints and edge resistance',
728 'Reduced motion controls and touch behavior',
729 'Advanced curves, damping, and inner magnet',
730 'Custom selector targeting',
731 ]);
732 }
733 }
734
735 /**
736 * Build magnetic options array.
737 *
738 * @param array<string, mixed> $settings Settings.
739 *
740 * @return array<string, mixed>
741 */
742 protected function get_magnet_options(array $settings): array
743 {
744 return [
745 'enabled' => (($settings['kng_magnet_enable'] ?? 'yes') === 'yes'),
746 'strength' => (int) ($settings['kng_magnet_strength']['size'] ?? 25),
747 'radius' => (int) ($settings['kng_magnet_radius']['size'] ?? 120),
748 'maxOffset' => (int) ($settings['kng_magnet_max_offset']['size'] ?? 12),
749 'returnSpeed' => (int) ($settings['kng_magnet_return_speed']['size'] ?? 40),
750 'easing' => $settings['kng_magnet_easing'] ?? 'smooth',
751 ];
752 }
753
754 /**
755 * Sanitize size.
756 *
757 * @param string $size Size.
758 *
759 * @return string
760 */
761 protected function sanitize_size(string $size): string
762 {
763 $allowed = ['small', 'medium', 'large'];
764 return in_array($size, $allowed, true) ? $size : 'medium';
765 }
766
767 /**
768 * Sanitize icon position.
769 *
770 * @param string $position Position.
771 *
772 * @return string
773 */
774 protected function sanitize_icon_position(string $position): string
775 {
776 $allowed = ['left', 'right'];
777 return in_array($position, $allowed, true) ? $position : 'left';
778 }
779 }
780