PluginProbe
Elementor Website Builder – more than just a page builder / 3.21.7
Elementor Website Builder – more than just a page builder v3.21.7
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.21.7, at modules/shapes/widgets/text-path.php

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