PluginProbe
Elementor Website Builder – more than just a page builder / 3.26.3
Elementor Website Builder – more than just a page builder v3.26.3
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / shapes / widgets / text-path.php

text-path.php in Elementor Website Builder – more than just a page builder 3.26.3, at modules/shapes/widgets/text-path.php

708 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Shapes\Widgets;
4
5 use Elementor\Controls_Manager;
6 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
7 use Elementor\Group_Control_Typography;
8 use Elementor\Modules\Shapes\Module as Shapes_Module;
9 use Elementor\Group_Control_Text_Stroke;
10 use Elementor\Plugin;
11 use Elementor\Widget_Base;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly.
15 }
16
17 /**
18 * Elementor WordArt widget.
19 *
20 * Elementor widget that displays text along SVG path.
21 *
22 */
23 class TextPath extends Widget_Base {
24
25 const DEFAULT_PATH_FILL = '#E8178A';
26
27 /**
28 * Get widget name.
29 *
30 * Retrieve Text Path widget name.
31 *
32 * @return string Widget name.
33 * @access public
34 *
35 */
36 public function get_name() {
37 return 'text-path';
38 }
39
40 public function get_group_name() {
41 return 'shapes';
42 }
43
44 /**
45 * Get widget title.
46 *
47 * Retrieve Text Path widget title.
48 *
49 * @return string Widget title.
50 * @access public
51 *
52 */
53 public function get_title() {
54 return esc_html__( 'Text Path', 'elementor' );
55 }
56
57 /**
58 * Get widget icon.
59 *
60 * Retrieve Text Path widget icon.
61 *
62 * @return string Widget icon.
63 * @access public
64 *
65 */
66 public function get_icon() {
67 return 'eicon-wordart';
68 }
69
70 /**
71 * Get widget keywords.
72 *
73 * Retrieve the list of keywords the widget belongs to.
74 *
75 * @return array Widget keywords.
76 * @access public
77 *
78 */
79 public function get_keywords() {
80 return [ 'text path', 'word path', 'text on path', 'wordart', 'word art' ];
81 }
82
83 /**
84 * Get style dependencies.
85 *
86 * Retrieve the list of style dependencies the widget requires.
87 *
88 * @since 3.24.0
89 * @access public
90 *
91 * @return array Widget style dependencies.
92 */
93 public function get_style_depends(): array {
94 return [ 'widget-text-path' ];
95 }
96
97 /**
98 * Register content controls under content tab.
99 */
100 protected function register_content_tab() {
101 $this->start_controls_section(
102 'section_content_text_path',
103 [
104 'label' => esc_html__( 'Text Path', 'elementor' ),
105 'tab' => Controls_Manager::TAB_CONTENT,
106 ]
107 );
108
109 $this->add_control(
110 'text',
111 [
112 'label' => esc_html__( 'Text', 'elementor' ),
113 'type' => Controls_Manager::TEXT,
114 'label_block' => true,
115 'default' => esc_html__( 'Add Your Curvy Text Here', 'elementor' ),
116 'frontend_available' => true,
117 'render_type' => 'none',
118 'dynamic' => [
119 'active' => true,
120 ],
121 ]
122 );
123
124 $this->add_control(
125 'path',
126 [
127 'label' => esc_html__( 'Path Type', 'elementor' ),
128 'type' => Controls_Manager::SELECT,
129 'options' => Shapes_Module::get_paths(),
130 'default' => 'wave',
131 ]
132 );
133
134 $this->add_control(
135 'custom_path',
136 [
137 'label' => esc_html__( 'SVG', 'elementor' ),
138 'type' => Controls_Manager::MEDIA,
139 'media_types' => [
140 'svg',
141 ],
142 'condition' => [
143 'path' => 'custom',
144 ],
145 'dynamic' => [
146 'active' => true,
147 ],
148 'description' => sprintf(
149 '%1$s <a target="_blank" href="https://go.elementor.com/text-path-create-paths/">%2$s</a>',
150 esc_html__( 'Want to create custom text paths with SVG?', 'elementor' ),
151 esc_html__( 'Learn more', 'elementor' )
152 ),
153 ]
154 );
155
156 $this->add_control(
157 'link',
158 [
159 'label' => esc_html__( 'Link', 'elementor' ),
160 'type' => Controls_Manager::URL,
161 'label_block' => true,
162 'dynamic' => [
163 'active' => true,
164 ],
165 'placeholder' => esc_html__( 'Paste URL or type', 'elementor' ),
166 'frontend_available' => true,
167 ]
168 );
169
170 $this->add_responsive_control(
171 'align',
172 [
173 'label' => esc_html__( 'Alignment', 'elementor' ),
174 'type' => Controls_Manager::CHOOSE,
175 'default' => '',
176 'options' => [
177 'left' => [
178 'title' => esc_html__( 'Left', 'elementor' ),
179 'icon' => 'eicon-text-align-left',
180 ],
181 'center' => [
182 'title' => esc_html__( 'Center', 'elementor' ),
183 'icon' => 'eicon-text-align-center',
184 ],
185 'right' => [
186 'title' => esc_html__( 'Right', 'elementor' ),
187 'icon' => 'eicon-text-align-right',
188 ],
189 ],
190 'selectors' => [
191 '{{WRAPPER}}' => '--alignment: {{VALUE}}',
192 ],
193 'frontend_available' => true,
194 ]
195 );
196
197 $this->add_control(
198 'text_path_direction',
199 [
200 'label' => esc_html__( 'Text Direction', 'elementor' ),
201 'type' => Controls_Manager::SELECT,
202 'default' => '',
203 'options' => [
204 '' => esc_html__( 'Default', 'elementor' ),
205 'rtl' => esc_html__( 'RTL', 'elementor' ),
206 'ltr' => esc_html__( 'LTR', 'elementor' ),
207 ],
208 'selectors' => [
209 '{{WRAPPER}}' => '--direction: {{VALUE}}',
210 ],
211 'frontend_available' => true,
212 ]
213 );
214
215 $this->add_control(
216 'show_path',
217 [
218 'label' => esc_html__( 'Show Path', 'elementor' ),
219 'type' => Controls_Manager::SWITCHER,
220 'label_on' => esc_html__( 'On', 'elementor' ),
221 'label_off' => esc_html__( 'Off', 'elementor' ),
222 'return_value' => self::DEFAULT_PATH_FILL,
223 'separator' => 'before',
224 'default' => '',
225 'selectors' => [
226 '{{WRAPPER}}' => '--path-stroke: {{VALUE}}; --path-fill: transparent;',
227 ],
228 ]
229 );
230
231 $this->end_controls_section();
232 }
233
234 /**
235 * Register style controls under style tab.
236 */
237 protected function register_style_tab() {
238 /**
239 * Text Path styling section.
240 */
241 $this->start_controls_section(
242 'section_style_text_path',
243 [
244 'label' => esc_html__( 'Text Path', 'elementor' ),
245 'tab' => Controls_Manager::TAB_STYLE,
246 ]
247 );
248
249 $this->add_responsive_control(
250 'size',
251 [
252 'label' => esc_html__( 'Size', 'elementor' ),
253 'type' => Controls_Manager::SLIDER,
254 'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
255 'range' => [
256 '%' => [
257 'min' => 0,
258 'max' => 100,
259 'step' => 10,
260 ],
261 'px' => [
262 'max' => 800,
263 'step' => 50,
264 ],
265 ],
266 'default' => [
267 'size' => 500,
268 ],
269 'tablet_default' => [
270 'size' => 500,
271 ],
272 'mobile_default' => [
273 'size' => 500,
274 ],
275 'selectors' => [
276 '{{WRAPPER}}' => '--width: {{SIZE}}{{UNIT}};',
277 ],
278 ]
279 );
280
281 $this->add_responsive_control(
282 'rotation',
283 [
284 'label' => esc_html__( 'Rotate', 'elementor' ),
285 'type' => Controls_Manager::SLIDER,
286 'size_units' => [ 'deg', 'grad', 'rad', 'turn', 'custom' ],
287 'default' => [
288 'unit' => 'deg',
289 ],
290 'tablet_default' => [
291 'unit' => 'deg',
292 ],
293 'mobile_default' => [
294 'unit' => 'deg',
295 ],
296 'selectors' => [
297 '{{WRAPPER}}' => '--rotate: {{SIZE}}{{UNIT}};',
298 ],
299 ]
300 );
301
302 $this->add_control(
303 'text_heading',
304 [
305 'label' => esc_html__( 'Text', 'elementor' ),
306 'type' => Controls_Manager::HEADING,
307 ]
308 );
309
310 $this->add_group_control(
311 Group_Control_Typography::get_type(),
312 [
313 'name' => 'text_typography',
314 'selector' => '{{WRAPPER}}',
315 'global' => [
316 'default' => Global_Typography::TYPOGRAPHY_TEXT,
317 ],
318 'fields_options' => [
319 'font_size' => [
320 'default' => [
321 'size' => '20',
322 'unit' => 'px',
323 ],
324 'size_units' => [ 'px' ],
325 ],
326 // Text decoration isn't an inherited property, so it's required to explicitly
327 // target the specific `textPath` element.
328 'text_decoration' => [
329 'selectors' => [
330 '{{WRAPPER}} textPath' => 'text-decoration: {{VALUE}};',
331 ],
332 ],
333 ],
334 ]
335 );
336
337 $this->add_group_control(
338 Group_Control_Text_Stroke::get_type(),
339 [
340 'name' => 'text_stroke',
341 'selector' => '{{WRAPPER}} textPath',
342 ]
343 );
344
345 $this->add_responsive_control(
346 'word_spacing',
347 [
348 'label' => esc_html__( 'Word Spacing', 'elementor' ),
349 'type' => Controls_Manager::SLIDER,
350 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
351 'range' => [
352 'px' => [
353 'min' => -20,
354 'max' => 20,
355 ],
356 'em' => [
357 'min' => -1,
358 'max' => 1,
359 ],
360 'rem' => [
361 'min' => -1,
362 'max' => 1,
363 ],
364 ],
365 'default' => [
366 'size' => '',
367 ],
368 'tablet_default' => [
369 'size' => '',
370 ],
371 'mobile_default' => [
372 'size' => '',
373 ],
374 'selectors' => [
375 '{{WRAPPER}}' => '--word-spacing: {{SIZE}}{{UNIT}};',
376 ],
377 ]
378 );
379
380 $this->add_control(
381 'start_point',
382 [
383 'label' => esc_html__( 'Starting Point', 'elementor' ) . ' (%)',
384 'type' => Controls_Manager::SLIDER,
385 'size_units' => [ '%' ],
386 'range' => [
387 'px' => [
388 'min' => -100,
389 'max' => 100,
390 'step' => 1,
391 ],
392 ],
393 'default' => [
394 'unit' => '%',
395 'size' => 0,
396 ],
397 'frontend_available' => true,
398 'render_type' => 'none',
399 ]
400 );
401
402 $this->start_controls_tabs( 'text_style' );
403
404 /**
405 * Normal tab.
406 */
407 $this->start_controls_tab(
408 'text_normal',
409 [
410 'label' => esc_html__( 'Normal', 'elementor' ),
411 ]
412 );
413
414 $this->add_control(
415 'text_color_normal',
416 [
417 'label' => esc_html__( 'Color', 'elementor' ),
418 'type' => Controls_Manager::COLOR,
419 'default' => '',
420 'selectors' => [
421 '{{WRAPPER}}' => '--text-color: {{VALUE}};',
422 ],
423 ]
424 );
425
426 $this->end_controls_tab();
427
428 /**
429 * Hover tab.
430 */
431 $this->start_controls_tab(
432 'text_hover',
433 [
434 'label' => esc_html__( 'Hover', 'elementor' ),
435 ]
436 );
437
438 $this->add_control(
439 'text_color_hover',
440 [
441 'label' => esc_html__( 'Color', 'elementor' ),
442 'type' => Controls_Manager::COLOR,
443 'default' => '',
444 'selectors' => [
445 '{{WRAPPER}}' => '--text-color-hover: {{VALUE}};',
446 ],
447 ]
448 );
449
450 $this->add_control(
451 'hover_animation',
452 [
453 'label' => esc_html__( 'Hover Animation', 'elementor' ),
454 'type' => Controls_Manager::HOVER_ANIMATION,
455 ]
456 );
457
458 $this->add_control(
459 'hover_transition',
460 [
461 'label' => esc_html__( 'Transition Duration', 'elementor' ),
462 'type' => Controls_Manager::SLIDER,
463 'size_units' => [ 's', 'ms', 'custom' ],
464 'default' => [
465 'unit' => 's',
466 'size' => 0.3,
467 ],
468 'selectors' => [
469 '{{WRAPPER}}' => '--transition: {{SIZE}}{{UNIT}}',
470 ],
471 ]
472 );
473
474 $this->end_controls_tab();
475
476 $this->end_controls_tabs();
477
478 $this->end_controls_section();
479
480 /**
481 * Path styling section.
482 */
483 $this->start_controls_section(
484 'section_style_path',
485 [
486 'label' => esc_html__( 'Path', 'elementor' ),
487 'tab' => Controls_Manager::TAB_STYLE,
488 'condition' => [
489 'show_path!' => '',
490 ],
491 ]
492 );
493
494 $this->start_controls_tabs( 'path_style' );
495
496 /**
497 * Normal tab.
498 */
499 $this->start_controls_tab(
500 'path_normal',
501 [
502 'label' => esc_html__( 'Normal', 'elementor' ),
503 ]
504 );
505
506 $this->add_control(
507 'path_fill_normal',
508 [
509 'label' => esc_html__( 'Color', 'elementor' ),
510 'type' => Controls_Manager::COLOR,
511 'default' => '',
512 'selectors' => [
513 '{{WRAPPER}}' => '--path-fill: {{VALUE}};',
514 ],
515 ]
516 );
517
518 $this->add_control(
519 'stroke_heading_normal',
520 [
521 'label' => esc_html__( 'Stroke', 'elementor' ),
522 'type' => Controls_Manager::HEADING,
523 ]
524 );
525
526 $this->add_control(
527 'stroke_color_normal',
528 [
529 'label' => esc_html__( 'Color', 'elementor' ),
530 'type' => Controls_Manager::COLOR,
531 'default' => self::DEFAULT_PATH_FILL,
532 'selectors' => [
533 '{{WRAPPER}}' => '--stroke-color: {{VALUE}};',
534 ],
535 ]
536 );
537
538 $this->add_control(
539 'stroke_width_normal',
540 [
541 'label' => esc_html__( 'Width', 'elementor' ),
542 'type' => Controls_Manager::SLIDER,
543 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
544 'default' => [
545 'size' => 1,
546 ],
547 'range' => [
548 'px' => [
549 'min' => 1,
550 'max' => 20,
551 ],
552 'em' => [
553 'max' => 2,
554 ],
555 'rem' => [
556 'max' => 2,
557 ],
558 ],
559 'selectors' => [
560 '{{WRAPPER}}' => '--stroke-width: {{SIZE}}{{UNIT}}',
561 ],
562 ]
563 );
564
565 $this->end_controls_tab();
566
567 /**
568 * Hover tab.
569 */
570 $this->start_controls_tab(
571 'path_hover',
572 [
573 'label' => esc_html__( 'Hover', 'elementor' ),
574 ]
575 );
576
577 $this->add_control(
578 'path_fill_hover',
579 [
580 'label' => esc_html__( 'Color', 'elementor' ),
581 'type' => Controls_Manager::COLOR,
582 'default' => '',
583 'selectors' => [
584 '{{WRAPPER}}' => '--path-fill-hover: {{VALUE}};',
585 ],
586 ]
587 );
588
589 $this->add_control(
590 'stroke_heading_hover',
591 [
592 'label' => esc_html__( 'Stroke', 'elementor' ),
593 'type' => Controls_Manager::HEADING,
594 ]
595 );
596
597 $this->add_control(
598 'stroke_color_hover',
599 [
600 'label' => esc_html__( 'Color', 'elementor' ),
601 'type' => Controls_Manager::COLOR,
602 'default' => '',
603 'selectors' => [
604 '{{WRAPPER}}' => '--stroke-color-hover: {{VALUE}};',
605 ],
606 ]
607 );
608
609 $this->add_control(
610 'stroke_width_hover',
611 [
612 'label' => esc_html__( 'Width', 'elementor' ),
613 'type' => Controls_Manager::SLIDER,
614 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
615 'default' => [
616 'size' => '',
617 ],
618 'range' => [
619 'px' => [
620 'min' => 1,
621 'max' => 20,
622 ],
623 'em' => [
624 'max' => 2,
625 ],
626 'rem' => [
627 'max' => 2,
628 ],
629 ],
630 'selectors' => [
631 '{{WRAPPER}}' => '--stroke-width-hover: {{SIZE}}{{UNIT}}',
632 ],
633 ]
634 );
635
636 $this->add_control(
637 'stroke_transition',
638 [
639 'label' => esc_html__( 'Transition Duration', 'elementor' ),
640 'type' => Controls_Manager::SLIDER,
641 'size_units' => [ 's', 'ms', 'custom' ],
642 'default' => [
643 'unit' => 's',
644 'size' => 0.3,
645 ],
646 'selectors' => [
647 '{{WRAPPER}}' => '--stroke-transition: {{SIZE}}{{UNIT}}',
648 ],
649 ]
650 );
651
652 $this->end_controls_tab();
653
654 $this->end_controls_tabs();
655
656 $this->end_controls_section();
657 }
658
659 /**
660 * Register Text Path widget controls.
661 *
662 * Adds different input fields to allow the user to change and customize the widget settings.
663 *
664 * @access protected
665 */
666 protected function register_controls() {
667 $this->register_content_tab();
668 $this->register_style_tab();
669 }
670
671 /**
672 * Render Text Path widget output on the frontend.
673 *
674 * Written in PHP and used to generate the final HTML.
675 *
676 * @access protected
677 */
678 protected function render() {
679 $settings = $this->get_settings_for_display();
680
681 // Get the path URL.
682 $path_url = ( 'custom' === $settings['path'] )
683 ? wp_get_attachment_url( $settings['custom_path']['id'] )
684 : Shapes_Module::get_path_url( $settings['path'] );
685
686 // Remove the HTTP protocol to prevent Mixed Content error.
687 $path_url = preg_replace( '/^https?:/i', '', $path_url );
688
689 // Add Text Path attributes.
690 $this->add_render_attribute( 'text_path', [
691 'class' => 'e-text-path',
692 'data-text' => htmlentities( esc_attr( $settings['text'] ) ),
693 'data-url' => esc_url( $path_url ),
694 'data-link-url' => esc_url( $settings['link']['url'] ?? '' ),
695 ] );
696
697 // Add hover animation.
698 if ( ! empty( $settings['hover_animation'] ) ) {
699 $this->add_render_attribute( 'text_path', 'class', 'elementor-animation-' . $settings['hover_animation'] );
700 }
701
702 // Render.
703 ?>
704 <div <?php $this->print_render_attribute_string( 'text_path' ); ?>></div>
705 <?php
706 }
707 }
708