PluginProbe
Elementor Website Builder – more than just a page builder / 3.10.0-dev1
Elementor Website Builder – more than just a page builder v3.10.0-dev1
4.3.0-beta3 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 All 452 releases
elementor / modules / shapes / widgets / text-path.php

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

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