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

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