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

692 lines 14.1 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\Widget_Base;
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly.
14 }
15
16 /**
17 * Elementor WordArt widget.
18 *
19 * Elementor widget that displays text along SVG path.
20 *
21 */
22 class TextPath extends Widget_Base {
23
24 const DEFAULT_PATH_FILL = '#E8178A';
25
26 /**
27 * Get widget name.
28 *
29 * Retrieve Text Path widget name.
30 *
31 * @return string Widget name.
32 * @access public
33 *
34 */
35 public function get_name() {
36 return 'text-path';
37 }
38
39 /**
40 * Get widget title.
41 *
42 * Retrieve Text Path widget title.
43 *
44 * @return string Widget title.
45 * @access public
46 *
47 */
48 public function get_title() {
49 return esc_html__( 'Text Path', 'elementor' );
50 }
51
52 /**
53 * Get widget icon.
54 *
55 * Retrieve Text Path widget icon.
56 *
57 * @return string Widget icon.
58 * @access public
59 *
60 */
61 public function get_icon() {
62 return 'eicon-wordart';
63 }
64
65 /**
66 * Get widget keywords.
67 *
68 * Retrieve the list of keywords the widget belongs to.
69 *
70 * @return array Widget keywords.
71 * @access public
72 *
73 */
74 public function get_keywords() {
75 return [ 'text path', 'word path', 'text on path', 'wordart', 'word art' ];
76 }
77
78 /**
79 * Register content controls under content tab.
80 */
81 protected function register_content_tab() {
82 $this->start_controls_section(
83 'section_content_text_path',
84 [
85 'label' => esc_html__( 'Text Path', 'elementor' ),
86 'tab' => Controls_Manager::TAB_CONTENT,
87 ]
88 );
89
90 $this->add_control(
91 'text',
92 [
93 'label' => esc_html__( 'Text', 'elementor' ),
94 'type' => Controls_Manager::TEXT,
95 'label_block' => true,
96 'default' => esc_html__( 'Add Your Curvy Text Here', 'elementor' ),
97 'frontend_available' => true,
98 'render_type' => 'none',
99 'dynamic' => [
100 'active' => true,
101 ],
102 ]
103 );
104
105 $this->add_control(
106 'path',
107 [
108 'label' => esc_html__( 'Path Type', 'elementor' ),
109 'type' => Controls_Manager::SELECT,
110 'options' => Shapes_Module::get_paths(),
111 'default' => 'wave',
112 ]
113 );
114
115 $this->add_control(
116 'custom_path',
117 [
118 'label' => esc_html__( 'SVG', 'elementor' ),
119 'type' => Controls_Manager::MEDIA,
120 'media_types' => [
121 'svg',
122 ],
123 'condition' => [
124 'path' => 'custom',
125 ],
126 'dynamic' => [
127 'active' => true,
128 ],
129 'description' => sprintf(
130 /* translators: %1$s Link open tag, %2$s: Link close tag. */
131 esc_html__( 'Want to create custom text paths with SVG? %1$sLearn More%2$s', 'elementor' ),
132 '<a target="_blank" href="https://go.elementor.com/text-path-create-paths/">',
133 '</a>'
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' ],
237 'range' => [
238 '%' => [
239 'min' => 0,
240 'max' => 100,
241 'step' => 10,
242 ],
243 'px' => [
244 'min' => 0,
245 'max' => 800,
246 'step' => 50,
247 ],
248 ],
249 'default' => [
250 'unit' => 'px',
251 'size' => 500,
252 ],
253 'tablet_default' => [
254 'unit' => 'px',
255 'size' => 500,
256 ],
257 'mobile_default' => [
258 'unit' => 'px',
259 'size' => 500,
260 ],
261 'selectors' => [
262 '{{WRAPPER}}' => '--width: {{SIZE}}{{UNIT}};',
263 ],
264 ]
265 );
266
267 $this->add_responsive_control(
268 'rotation',
269 [
270 'label' => esc_html__( 'Rotate', 'elementor' ),
271 'type' => Controls_Manager::SLIDER,
272 'size_units' => [ 'deg' ],
273 'range' => [
274 'deg' => [
275 'min' => 0,
276 'max' => 360,
277 'step' => 1,
278 ],
279 ],
280 'default' => [
281 'unit' => 'deg',
282 'size' => '',
283 ],
284 'tablet_default' => [
285 'unit' => 'deg',
286 'size' => '',
287 ],
288 'mobile_default' => [
289 'unit' => 'deg',
290 'size' => '',
291 ],
292 'selectors' => [
293 '{{WRAPPER}}' => '--rotate: {{SIZE}}{{UNIT}};',
294 ],
295 ]
296 );
297
298 $this->add_control(
299 'text_heading',
300 [
301 'label' => esc_html__( 'Text', 'elementor' ),
302 'type' => Controls_Manager::HEADING,
303 ]
304 );
305
306 $this->add_group_control(
307 Group_Control_Typography::get_type(),
308 [
309 'name' => 'text_typography',
310 'selector' => '{{WRAPPER}}',
311 'global' => [
312 'default' => Global_Typography::TYPOGRAPHY_TEXT,
313 ],
314 'fields_options' => [
315 'font_size' => [
316 'default' => [
317 'size' => '20',
318 'unit' => 'px',
319 ],
320 'size_units' => [ 'px' ],
321 ],
322 // Text decoration isn't an inherited property, so it's required to explicitly
323 // target the specific `textPath` element.
324 'text_decoration' => [
325 'selectors' => [
326 '{{WRAPPER}} textPath' => 'text-decoration: {{VALUE}};',
327 ],
328 ],
329 ],
330 ]
331 );
332
333 $this->add_responsive_control(
334 'word_spacing',
335 [
336 'label' => esc_html__( 'Word Spacing', 'elementor' ),
337 'type' => Controls_Manager::SLIDER,
338 'size_units' => [ 'px' ],
339 'range' => [
340 'px' => [
341 'min' => -20,
342 'max' => 20,
343 'step' => 1,
344 ],
345 ],
346 'default' => [
347 'unit' => 'px',
348 'size' => '',
349 ],
350 'tablet_default' => [
351 'unit' => 'px',
352 'size' => '',
353 ],
354 'mobile_default' => [
355 'unit' => 'px',
356 'size' => '',
357 ],
358 'selectors' => [
359 '{{WRAPPER}}' => '--word-spacing: {{SIZE}}{{UNIT}};',
360 ],
361 ]
362 );
363
364 $this->add_control(
365 'start_point',
366 [
367 'label' => esc_html__( 'Starting Point', 'elementor' ),
368 'type' => Controls_Manager::SLIDER,
369 'size_units' => [ '%' ],
370 'range' => [
371 'px' => [
372 'min' => -100,
373 'max' => 100,
374 'step' => 1,
375 ],
376 ],
377 'default' => [
378 'unit' => '%',
379 'size' => 0,
380 ],
381 'frontend_available' => true,
382 'render_type' => 'none',
383 ]
384 );
385
386 $this->start_controls_tabs( 'text_style' );
387
388 /**
389 * Normal tab.
390 */
391 $this->start_controls_tab(
392 'text_normal',
393 [
394 'label' => esc_html__( 'Normal', 'elementor' ),
395 ]
396 );
397
398 $this->add_control(
399 'text_color_normal',
400 [
401 'label' => esc_html__( 'Color', 'elementor' ),
402 'type' => Controls_Manager::COLOR,
403 'default' => '',
404 'selectors' => [
405 '{{WRAPPER}}' => '--text-color: {{VALUE}};',
406 ],
407 ]
408 );
409
410 $this->end_controls_tab();
411
412 /**
413 * Hover tab.
414 */
415 $this->start_controls_tab(
416 'text_hover',
417 [
418 'label' => esc_html__( 'Hover', 'elementor' ),
419 ]
420 );
421
422 $this->add_control(
423 'text_color_hover',
424 [
425 'label' => esc_html__( 'Color', 'elementor' ),
426 'type' => Controls_Manager::COLOR,
427 'default' => '',
428 'selectors' => [
429 '{{WRAPPER}}' => '--text-color-hover: {{VALUE}};',
430 ],
431 ]
432 );
433
434 $this->add_control(
435 'hover_animation',
436 [
437 'label' => esc_html__( 'Hover Animation', 'elementor' ),
438 'type' => Controls_Manager::HOVER_ANIMATION,
439 ]
440 );
441
442 $this->add_control(
443 'hover_transition',
444 [
445 'label' => esc_html__( 'Transition Duration', 'elementor' ),
446 'type' => Controls_Manager::SLIDER,
447 'default' => [
448 'size' => 0.3,
449 'unit' => 's',
450 ],
451 'range' => [
452 's' => [
453 'min' => 0,
454 'max' => 3,
455 'step' => 0.1,
456 ],
457 ],
458 'selectors' => [
459 '{{WRAPPER}}' => '--transition: {{SIZE}}{{UNIT}}',
460 ],
461 ]
462 );
463
464 $this->end_controls_tab();
465
466 $this->end_controls_tabs();
467
468 $this->end_controls_section();
469
470 /**
471 * Path styling section.
472 */
473 $this->start_controls_section(
474 'section_style_path',
475 [
476 'label' => esc_html__( 'Path', 'elementor' ),
477 'tab' => Controls_Manager::TAB_STYLE,
478 'condition' => [
479 'show_path!' => '',
480 ],
481 ]
482 );
483
484 $this->start_controls_tabs( 'path_style' );
485
486 /**
487 * Normal tab.
488 */
489 $this->start_controls_tab(
490 'path_normal',
491 [
492 'label' => esc_html__( 'Normal', 'elementor' ),
493 ]
494 );
495
496 $this->add_control(
497 'path_fill_normal',
498 [
499 'label' => esc_html__( 'Color', 'elementor' ),
500 'type' => Controls_Manager::COLOR,
501 'default' => '',
502 'selectors' => [
503 '{{WRAPPER}}' => '--path-fill: {{VALUE}};',
504 ],
505 ]
506 );
507
508 $this->add_control(
509 'stroke_heading_normal',
510 [
511 'label' => esc_html__( 'Stroke', 'elementor' ),
512 'type' => Controls_Manager::HEADING,
513 ]
514 );
515
516 $this->add_control(
517 'stroke_color_normal',
518 [
519 'label' => esc_html__( 'Color', 'elementor' ),
520 'type' => Controls_Manager::COLOR,
521 'default' => self::DEFAULT_PATH_FILL,
522 'selectors' => [
523 '{{WRAPPER}}' => '--stroke-color: {{VALUE}};',
524 ],
525 ]
526 );
527
528 $this->add_control(
529 'stroke_width_normal',
530 [
531 'label' => esc_html__( 'Width', 'elementor' ),
532 'type' => Controls_Manager::SLIDER,
533 'default' => [
534 'size' => 1,
535 'unit' => 'px',
536 ],
537 'range' => [
538 'px' => [
539 'min' => 0,
540 'max' => 20,
541 'step' => 1,
542 ],
543 ],
544 'selectors' => [
545 '{{WRAPPER}}' => '--stroke-width: {{SIZE}}{{UNIT}}',
546 ],
547 ]
548 );
549
550 $this->end_controls_tab();
551
552 /**
553 * Hover tab.
554 */
555 $this->start_controls_tab(
556 'path_hover',
557 [
558 'label' => esc_html__( 'Hover', 'elementor' ),
559 ]
560 );
561
562 $this->add_control(
563 'path_fill_hover',
564 [
565 'label' => esc_html__( 'Color', 'elementor' ),
566 'type' => Controls_Manager::COLOR,
567 'default' => '',
568 'selectors' => [
569 '{{WRAPPER}}' => '--path-fill-hover: {{VALUE}};',
570 ],
571 ]
572 );
573
574 $this->add_control(
575 'stroke_heading_hover',
576 [
577 'label' => esc_html__( 'Stroke', 'elementor' ),
578 'type' => Controls_Manager::HEADING,
579 ]
580 );
581
582 $this->add_control(
583 'stroke_color_hover',
584 [
585 'label' => esc_html__( 'Color', 'elementor' ),
586 'type' => Controls_Manager::COLOR,
587 'default' => '',
588 'selectors' => [
589 '{{WRAPPER}}' => '--stroke-color-hover: {{VALUE}};',
590 ],
591 ]
592 );
593
594 $this->add_control(
595 'stroke_width_hover',
596 [
597 'label' => esc_html__( 'Width', 'elementor' ),
598 'type' => Controls_Manager::SLIDER,
599 'default' => [
600 'size' => '',
601 'unit' => 'px',
602 ],
603 'range' => [
604 'px' => [
605 'min' => 0,
606 'max' => 20,
607 'step' => 1,
608 ],
609 ],
610 'selectors' => [
611 '{{WRAPPER}}' => '--stroke-width-hover: {{SIZE}}{{UNIT}}',
612 ],
613 ]
614 );
615
616 $this->add_control(
617 'stroke_transition',
618 [
619 'label' => esc_html__( 'Transition Duration', 'elementor' ),
620 'type' => Controls_Manager::SLIDER,
621 'default' => [
622 'size' => 0.3,
623 'unit' => 's',
624 ],
625 'range' => [
626 's' => [
627 'min' => 0,
628 'max' => 3,
629 'step' => 0.1,
630 ],
631 ],
632 'selectors' => [
633 '{{WRAPPER}}' => '--stroke-transition: {{SIZE}}{{UNIT}}',
634 ],
635 ]
636 );
637
638 $this->end_controls_tab();
639
640 $this->end_controls_tabs();
641
642 $this->end_controls_section();
643 }
644
645 /**
646 * Register Text Path widget controls.
647 *
648 * Adds different input fields to allow the user to change and customize the widget settings.
649 *
650 * @access protected
651 */
652 protected function register_controls() {
653 $this->register_content_tab();
654 $this->register_style_tab();
655 }
656
657 /**
658 * Render Text Path widget output on the frontend.
659 *
660 * Written in PHP and used to generate the final HTML.
661 *
662 * @access protected
663 */
664 protected function render() {
665 $settings = $this->get_settings_for_display();
666
667 // Get the shape SVG markup.
668 if ( 'custom' !== $settings['path'] ) {
669 $path_svg = Shapes_Module::get_path_svg( $settings['path'] );
670 } else {
671 $url = esc_url( $settings['custom_path']['url'] );
672 // Get the file contents only if it's svg.
673 $path_svg = ( 'svg' === pathinfo( $url, PATHINFO_EXTENSION ) ) ? file_get_contents( $url ) : '';
674 }
675
676 // Add Text Path text.
677 $this->add_render_attribute( 'text_path', 'class', 'e-text-path' );
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' ); ?> data-text="<?php echo esc_attr( $settings['text'] ); ?>">
687 <?php Utils::print_wp_kses_extended( $path_svg, [ 'svg' ] ); ?>
688 </div>
689 <?php
690 }
691 }
692