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

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