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

678 lines 14.0 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 'min' => 0,
246 'max' => 800,
247 'step' => 50,
248 ],
249 ],
250 'default' => [
251 'size' => 500,
252 ],
253 'tablet_default' => [
254 'size' => 500,
255 ],
256 'mobile_default' => [
257 'size' => 500,
258 ],
259 'selectors' => [
260 '{{WRAPPER}}' => '--width: {{SIZE}}{{UNIT}};',
261 ],
262 ]
263 );
264
265 $this->add_responsive_control(
266 'rotation',
267 [
268 'label' => esc_html__( 'Rotate', 'elementor' ),
269 'type' => Controls_Manager::SLIDER,
270 'size_units' => [ 'deg', 'grad', 'rad', 'turn', 'custom' ],
271 'default' => [
272 'unit' => 'deg',
273 ],
274 'tablet_default' => [
275 'unit' => 'deg',
276 ],
277 'mobile_default' => [
278 'unit' => 'deg',
279 ],
280 'selectors' => [
281 '{{WRAPPER}}' => '--rotate: {{SIZE}}{{UNIT}};',
282 ],
283 ]
284 );
285
286 $this->add_control(
287 'text_heading',
288 [
289 'label' => esc_html__( 'Text', 'elementor' ),
290 'type' => Controls_Manager::HEADING,
291 ]
292 );
293
294 $this->add_group_control(
295 Group_Control_Typography::get_type(),
296 [
297 'name' => 'text_typography',
298 'selector' => '{{WRAPPER}}',
299 'global' => [
300 'default' => Global_Typography::TYPOGRAPHY_TEXT,
301 ],
302 'fields_options' => [
303 'font_size' => [
304 'default' => [
305 'size' => '20',
306 'unit' => 'px',
307 ],
308 'size_units' => [ 'px' ],
309 ],
310 // Text decoration isn't an inherited property, so it's required to explicitly
311 // target the specific `textPath` element.
312 'text_decoration' => [
313 'selectors' => [
314 '{{WRAPPER}} textPath' => 'text-decoration: {{VALUE}};',
315 ],
316 ],
317 ],
318 ]
319 );
320
321 $this->add_group_control(
322 Group_Control_Text_Stroke::get_type(),
323 [
324 'name' => 'text_stroke',
325 'selector' => '{{WRAPPER}} textPath',
326 ]
327 );
328
329 $this->add_responsive_control(
330 'word_spacing',
331 [
332 'label' => esc_html__( 'Word Spacing', 'elementor' ),
333 'type' => Controls_Manager::SLIDER,
334 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
335 'range' => [
336 'px' => [
337 'min' => -20,
338 'max' => 20,
339 'step' => 1,
340 ],
341 'em' => [
342 'min' => -1,
343 'max' => 1,
344 'step' => 0.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 'default' => [
526 'size' => 1,
527 ],
528 'range' => [
529 'px' => [
530 'min' => 0,
531 'max' => 20,
532 'step' => 1,
533 ],
534 ],
535 'selectors' => [
536 '{{WRAPPER}}' => '--stroke-width: {{SIZE}}{{UNIT}}',
537 ],
538 ]
539 );
540
541 $this->end_controls_tab();
542
543 /**
544 * Hover tab.
545 */
546 $this->start_controls_tab(
547 'path_hover',
548 [
549 'label' => esc_html__( 'Hover', 'elementor' ),
550 ]
551 );
552
553 $this->add_control(
554 'path_fill_hover',
555 [
556 'label' => esc_html__( 'Color', 'elementor' ),
557 'type' => Controls_Manager::COLOR,
558 'default' => '',
559 'selectors' => [
560 '{{WRAPPER}}' => '--path-fill-hover: {{VALUE}};',
561 ],
562 ]
563 );
564
565 $this->add_control(
566 'stroke_heading_hover',
567 [
568 'label' => esc_html__( 'Stroke', 'elementor' ),
569 'type' => Controls_Manager::HEADING,
570 ]
571 );
572
573 $this->add_control(
574 'stroke_color_hover',
575 [
576 'label' => esc_html__( 'Color', 'elementor' ),
577 'type' => Controls_Manager::COLOR,
578 'default' => '',
579 'selectors' => [
580 '{{WRAPPER}}' => '--stroke-color-hover: {{VALUE}};',
581 ],
582 ]
583 );
584
585 $this->add_control(
586 'stroke_width_hover',
587 [
588 'label' => esc_html__( 'Width', 'elementor' ),
589 'type' => Controls_Manager::SLIDER,
590 'default' => [
591 'size' => '',
592 ],
593 'range' => [
594 'px' => [
595 'min' => 0,
596 'max' => 20,
597 'step' => 1,
598 ],
599 ],
600 'selectors' => [
601 '{{WRAPPER}}' => '--stroke-width-hover: {{SIZE}}{{UNIT}}',
602 ],
603 ]
604 );
605
606 $this->add_control(
607 'stroke_transition',
608 [
609 'label' => esc_html__( 'Transition Duration', 'elementor' ),
610 'type' => Controls_Manager::SLIDER,
611 'size_units' => [ 's', 'ms', 'custom' ],
612 'default' => [
613 'unit' => 's',
614 'size' => 0.3,
615 ],
616 'selectors' => [
617 '{{WRAPPER}}' => '--stroke-transition: {{SIZE}}{{UNIT}}',
618 ],
619 ]
620 );
621
622 $this->end_controls_tab();
623
624 $this->end_controls_tabs();
625
626 $this->end_controls_section();
627 }
628
629 /**
630 * Register Text Path widget controls.
631 *
632 * Adds different input fields to allow the user to change and customize the widget settings.
633 *
634 * @access protected
635 */
636 protected function register_controls() {
637 $this->register_content_tab();
638 $this->register_style_tab();
639 }
640
641 /**
642 * Render Text Path widget output on the frontend.
643 *
644 * Written in PHP and used to generate the final HTML.
645 *
646 * @access protected
647 */
648 protected function render() {
649 $settings = $this->get_settings_for_display();
650
651 // Get the path URL.
652 $path_url = ( 'custom' === $settings['path'] )
653 ? wp_get_attachment_url( $settings['custom_path']['id'] )
654 : Shapes_Module::get_path_url( $settings['path'] );
655
656 // Remove the HTTP protocol to prevent Mixed Content error.
657 $path_url = preg_replace( '/^https?:/i', '', $path_url );
658
659 // Add Text Path attributes.
660 $this->add_render_attribute( 'text_path', [
661 'class' => 'e-text-path',
662 'data-text' => htmlentities( esc_attr( $settings['text'] ) ),
663 'data-url' => esc_url( $path_url ),
664 'data-link-url' => esc_url( $settings['link']['url'] ?? '' ),
665 ] );
666
667 // Add hover animation.
668 if ( ! empty( $settings['hover_animation'] ) ) {
669 $this->add_render_attribute( 'text_path', 'class', 'elementor-animation-' . $settings['hover_animation'] );
670 }
671
672 // Render.
673 ?>
674 <div <?php $this->print_render_attribute_string( 'text_path' ); ?>></div>
675 <?php
676 }
677 }
678