Custom_JS.php
1 year ago
Hover_Effect.php
1 year ago
Image_Masking.php
2 months ago
Liquid_Glass_Effect.php
5 months ago
Post_Duplicator.php
2 months ago
Promotion.php
9 months ago
Reading_Progress.php
5 months ago
Scroll_to_Top.php
5 months ago
Table_of_Content.php
2 weeks ago
Vertical_Text_Orientation.php
7 months ago
Wrapper_Link.php
2 months ago
index.php
3 years ago
Image_Masking.php
640 lines
| 1 | <?php |
| 2 | |
| 3 | namespace Essential_Addons_Elementor\Extensions; |
| 4 | |
| 5 | use Elementor\Controls_Manager; |
| 6 | |
| 7 | if ( ! defined( 'ABSPATH' ) ) { |
| 8 | exit; |
| 9 | } |
| 10 | |
| 11 | class Image_Masking { |
| 12 | |
| 13 | private static $svg_dir_url = EAEL_PLUGIN_URL . 'assets/front-end/img/image-masking/svg-shapes/'; |
| 14 | /** |
| 15 | * Initialize hooks |
| 16 | */ |
| 17 | public function __construct() { |
| 18 | add_action( 'elementor/element/column/section_advanced/after_section_end', [ $this, 'register_controls' ] ); |
| 19 | add_action( 'elementor/element/section/section_advanced/after_section_end', [ $this, 'register_controls' ] ); |
| 20 | add_action( 'elementor/element/container/section_layout/after_section_end', [ $this, 'register_controls' ] ); |
| 21 | add_action( 'elementor/element/common/_section_style/after_section_end', [ $this, 'register_controls' ] ); |
| 22 | add_action( 'elementor/frontend/before_render', [ $this, 'before_render' ], 100 ); |
| 23 | add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); |
| 24 | add_filter( 'elementor/document/element/replace_id', [ $this, 'cleanup_settings_data' ] ); |
| 25 | add_filter( 'elementor/document/save/data', [ $this, 'cleanup_settings_data' ] ); |
| 26 | } |
| 27 | |
| 28 | public function cleanup_settings_data( $element_data ) { |
| 29 | |
| 30 | $prefixes = [ |
| 31 | 'eael_image_masking_', |
| 32 | 'eael_clip_', |
| 33 | 'eael_svg_paths_', |
| 34 | 'eael_image_morphing_' |
| 35 | ]; |
| 36 | |
| 37 | $clean_settings = function ( &$settings ) use ( $prefixes ) { |
| 38 | if ( empty( $settings[ 'eael_enable_image_masking' ] ) || 'yes' !== $settings[ 'eael_enable_image_masking' ] ) { |
| 39 | foreach ( array_keys( $settings ) as $key ) { |
| 40 | foreach ( $prefixes as $prefix ) { |
| 41 | if ( strncmp( $key, $prefix, \strlen( $prefix ) ) === 0 ) { |
| 42 | unset( $settings[ $key ] ); |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | // TODO: Remove this block after several versions once existing sites have re-saved and eael_svg_path is no longer present in the DB. |
| 49 | // Strip legacy eael_svg_path key from repeater items (replaced by eael_svg_code) |
| 50 | if ( ! empty( $settings['eael_svg_paths_custom'] ) && \is_array( $settings['eael_svg_paths_custom'] ) ) { |
| 51 | foreach ( $settings['eael_svg_paths_custom'] as &$item ) { |
| 52 | unset( $item['eael_svg_path'] ); |
| 53 | } |
| 54 | unset( $item ); |
| 55 | } |
| 56 | }; |
| 57 | |
| 58 | $walk = function ( &$element ) use ( &$walk, $clean_settings ) { |
| 59 | |
| 60 | if ( isset( $element['settings'] ) ) { |
| 61 | $clean_settings( $element['settings'] ); |
| 62 | } |
| 63 | |
| 64 | if ( isset( $element['page_settings'] ) ) { |
| 65 | $clean_settings( $element['page_settings'] ); |
| 66 | } |
| 67 | |
| 68 | if ( ! empty( $element['elements'] ) ) { |
| 69 | foreach ( $element['elements'] as &$child ) { |
| 70 | $walk( $child ); |
| 71 | } |
| 72 | } |
| 73 | }; |
| 74 | |
| 75 | $walk( $element_data ); |
| 76 | |
| 77 | return $element_data; |
| 78 | } |
| 79 | |
| 80 | public function enqueue_scripts() { |
| 81 | $data = [ 'svg_dir_url' => self::$svg_dir_url ]; |
| 82 | wp_localize_script( 'elementor-frontend', 'EAELImageMaskingConfig', $data ); |
| 83 | } |
| 84 | |
| 85 | private function clip_paths( $shape ){ |
| 86 | $shapes = [ |
| 87 | 'bavel' => 'polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%)', |
| 88 | 'rabbet' => 'polygon(0% 15%, 15% 15%, 15% 0%, 85% 0%, 85% 15%, 100% 15%, 100% 85%, 85% 85%, 85% 100%, 15% 100%, 15% 85%, 0% 85%)', |
| 89 | 'chevron-left' => 'polygon(100% 0%, 75% 50%, 100% 100%, 25% 100%, 0% 50%, 25% 0%)', |
| 90 | 'chevron-right' => 'polygon(75% 0%, 100% 50%, 75% 100%, 0% 100%, 25% 50%, 0% 0%)', |
| 91 | 'star' => 'polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)', |
| 92 | ]; |
| 93 | return $shapes[$shape] ?? ''; |
| 94 | } |
| 95 | private function masking_controllers( $element, $tab = '' ) { |
| 96 | |
| 97 | $condition = []; |
| 98 | if( '_hover' === $tab ) { |
| 99 | $element->add_control( |
| 100 | 'eael_image_masking_hover_effect', |
| 101 | [ |
| 102 | 'label' => esc_html__( 'Enable', 'essential-addons-for-elementor-lite' ), |
| 103 | 'type' => Controls_Manager::SWITCHER, |
| 104 | 'return_value' => 'yes', |
| 105 | ] |
| 106 | ); |
| 107 | $condition = [ |
| 108 | 'eael_image_masking_hover_effect' => 'yes', |
| 109 | ]; |
| 110 | } |
| 111 | |
| 112 | $condition['eael_image_masking_type'] = 'clip'; |
| 113 | $image_dir_url = EAEL_PLUGIN_URL . 'assets/front-end/img/image-masking/clip-paths/'; |
| 114 | $element->add_control( |
| 115 | 'eael_image_masking_clip_path' . $tab, |
| 116 | [ |
| 117 | 'label' => esc_html__( 'Select Clip Path', 'essential-addons-for-elementor-lite' ), |
| 118 | 'label_block' => true, |
| 119 | 'type' => Controls_Manager::CHOOSE, |
| 120 | 'options' => [ |
| 121 | 'bavel' => [ |
| 122 | 'title' => esc_html__( 'Bavel', 'essential-addons-for-elementor-lite' ), |
| 123 | 'image' => $image_dir_url . 'bavel.svg', |
| 124 | ], |
| 125 | 'rabbet' => [ |
| 126 | 'title' => esc_html__( 'Rabbet', 'essential-addons-for-elementor-lite' ), |
| 127 | 'image' => $image_dir_url . 'rabbet.svg', |
| 128 | ], |
| 129 | 'chevron-left' => [ |
| 130 | 'title' => esc_html__( 'Chevron Left', 'essential-addons-for-elementor-lite' ), |
| 131 | 'image' => $image_dir_url . 'chevron-left.svg', |
| 132 | ], |
| 133 | 'chevron-right' => [ |
| 134 | 'title' => esc_html__( 'Chevron Right', 'essential-addons-for-elementor-lite' ), |
| 135 | 'image' => $image_dir_url . 'chevron-right.svg', |
| 136 | ], |
| 137 | 'star' => [ |
| 138 | 'title' => esc_html__( 'Start', 'essential-addons-for-elementor-lite' ), |
| 139 | 'image' => $image_dir_url . 'star.svg', |
| 140 | ], |
| 141 | ], |
| 142 | 'default' => 'bavel', |
| 143 | 'toggle' => false, |
| 144 | 'image_choose' => true, |
| 145 | 'css_class' => 'eael-image-masking-choose', |
| 146 | 'condition' => array_merge( $condition, [ 'eael_image_masking_enable_custom_clip_path' . $tab . '!' => 'yes' ] ) |
| 147 | ] |
| 148 | ); |
| 149 | |
| 150 | $element->add_control( |
| 151 | 'eael_image_masking_enable_custom_clip_path' . $tab, |
| 152 | [ |
| 153 | 'label' => esc_html__( 'Use Custom Clip Path', 'essential-addons-for-elementor-lite' ), |
| 154 | 'type' => Controls_Manager::SWITCHER, |
| 155 | 'return_value' => 'yes', |
| 156 | 'condition' => $condition, |
| 157 | ] |
| 158 | ); |
| 159 | |
| 160 | $element->add_control( |
| 161 | 'eael_image_masking_custom_clip_path' . $tab, |
| 162 | [ |
| 163 | 'label' => '', |
| 164 | 'type' => Controls_Manager::TEXTAREA, |
| 165 | 'rows' => 10, |
| 166 | 'label_block' => true, |
| 167 | 'dynamic' => [ |
| 168 | 'active' => false, |
| 169 | ], |
| 170 | 'ai' => [ |
| 171 | 'active' => false, |
| 172 | ], |
| 173 | 'default' => 'clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%);', |
| 174 | 'placeholder' => 'clip-path: polygon(50% 0%, 0% 100%, 100% 100%);', |
| 175 | 'description' => __( 'Enter your custom clip path value. You can use <a href = "https://bennettfeely.com/clippy/" target = "_blank">Clippy</a> to generate your custom clip path.', 'essential-addons-for-elementor-lite' ), |
| 176 | 'condition' => array_merge( $condition, [ 'eael_image_masking_enable_custom_clip_path' . $tab => 'yes' ] ), |
| 177 | ] |
| 178 | ); |
| 179 | |
| 180 | $condition = [ 'eael_image_masking_type' => 'image' ]; |
| 181 | if( '_hover' === $tab ){ |
| 182 | $condition['eael_image_masking_hover_effect'] = 'yes'; |
| 183 | } |
| 184 | |
| 185 | $svg_url = EAEL_PLUGIN_URL . 'assets/front-end/img/image-masking/svg-shapes/'; |
| 186 | $element->add_control( |
| 187 | 'eael_image_masking_svg' . $tab, |
| 188 | [ |
| 189 | 'label' => esc_html__( 'Choose Shape', 'essential-addons-for-elementor-lite' ), |
| 190 | 'label_block' => true, |
| 191 | 'type' => Controls_Manager::CHOOSE, |
| 192 | 'options' => [ |
| 193 | 'polygon' => [ |
| 194 | 'title' => esc_html__( 'Polygon', 'essential-addons-for-elementor-lite' ), |
| 195 | 'image' => $svg_url . 'polygon.svg', |
| 196 | ], |
| 197 | 'rounded' => [ |
| 198 | 'title' => esc_html__( 'Rounded', 'essential-addons-for-elementor-lite' ), |
| 199 | 'image' => $svg_url . 'rounded.svg', |
| 200 | ], |
| 201 | 'arch-down' => [ |
| 202 | 'title' => esc_html__( 'Arch Down', 'essential-addons-for-elementor-lite' ), |
| 203 | 'image' => $svg_url . 'arch-down.svg', |
| 204 | ], |
| 205 | 'arch-group' => [ |
| 206 | 'title' => esc_html__( 'Arch Group', 'essential-addons-for-elementor-lite' ), |
| 207 | 'image' => $svg_url . 'arch-group.svg', |
| 208 | ], |
| 209 | 'arch-up' => [ |
| 210 | 'title' => esc_html__( 'Arch Up', 'essential-addons-for-elementor-lite' ), |
| 211 | 'image' => $svg_url . 'arch-up.svg', |
| 212 | ], |
| 213 | 'asterisk' => [ |
| 214 | 'title' => esc_html__( 'Asterisk', 'essential-addons-for-elementor-lite' ), |
| 215 | 'image' => $svg_url . 'asterisk.svg', |
| 216 | ], |
| 217 | 'blob' => [ |
| 218 | 'title' => esc_html__( 'Blob', 'essential-addons-for-elementor-lite' ), |
| 219 | 'image' => $svg_url . 'blob.svg', |
| 220 | ], |
| 221 | 'blocks' => [ |
| 222 | 'title' => esc_html__( 'Blocks', 'essential-addons-for-elementor-lite' ), |
| 223 | 'image' => $svg_url . 'blocks.svg', |
| 224 | ], |
| 225 | 'brash-1' => [ |
| 226 | 'title' => esc_html__( 'Brash 1', 'essential-addons-for-elementor-lite' ), |
| 227 | 'image' => $svg_url . 'brash-1.svg', |
| 228 | ], |
| 229 | 'brash-2' => [ |
| 230 | 'title' => esc_html__( 'Brash 2', 'essential-addons-for-elementor-lite' ), |
| 231 | 'image' => $svg_url . 'brash-2.svg', |
| 232 | ], |
| 233 | 'brash-3' => [ |
| 234 | 'title' => esc_html__( 'Brash 3', 'essential-addons-for-elementor-lite' ), |
| 235 | 'image' => $svg_url . 'brash-3.svg', |
| 236 | ], |
| 237 | 'burst' => [ |
| 238 | 'title' => esc_html__( 'Burst', 'essential-addons-for-elementor-lite' ), |
| 239 | 'image' => $svg_url . 'burst.svg', |
| 240 | ], |
| 241 | 'chat' => [ |
| 242 | 'title' => esc_html__( 'Chat', 'essential-addons-for-elementor-lite' ), |
| 243 | 'image' => $svg_url . 'chat.svg', |
| 244 | ], |
| 245 | 'hex-tile' => [ |
| 246 | 'title' => esc_html__( 'Hex Tile', 'essential-addons-for-elementor-lite' ), |
| 247 | 'image' => $svg_url . 'hex-tile.svg', |
| 248 | ], |
| 249 | 'leaf' => [ |
| 250 | 'title' => esc_html__( 'Leaf', 'essential-addons-for-elementor-lite' ), |
| 251 | 'image' => $svg_url . 'leaf.svg', |
| 252 | ], |
| 253 | 'oval' => [ |
| 254 | 'title' => esc_html__( 'Oval', 'essential-addons-for-elementor-lite' ), |
| 255 | 'image' => $svg_url . 'oval.svg', |
| 256 | ], |
| 257 | 'pixel-cross' => [ |
| 258 | 'title' => esc_html__( 'Pixel Cross', 'essential-addons-for-elementor-lite' ), |
| 259 | 'image' => $svg_url . 'pixel-cross.svg', |
| 260 | ], |
| 261 | 'quote' => [ |
| 262 | 'title' => esc_html__( 'Quote', 'essential-addons-for-elementor-lite' ), |
| 263 | 'image' => $svg_url . 'quote.svg', |
| 264 | ], |
| 265 | 'star-dimond' => [ |
| 266 | 'title' => esc_html__( 'Star Diamond', 'essential-addons-for-elementor-lite' ), |
| 267 | 'image' => $svg_url . 'star-dimond.svg', |
| 268 | ], |
| 269 | 'upload' => [ |
| 270 | 'title' => esc_html__( 'Upload', 'essential-addons-for-elementor-lite' ), |
| 271 | 'image' => $svg_url . 'upload.svg', |
| 272 | 'fullwidth' => true, |
| 273 | ], |
| 274 | ], |
| 275 | 'toggle' => false, |
| 276 | 'image_choose' => true, |
| 277 | 'css_class' => 'eael-image-masking-choose col-5', |
| 278 | 'default' => 'polygon', |
| 279 | 'condition' => $condition |
| 280 | ] |
| 281 | ); |
| 282 | |
| 283 | if ( !apply_filters('eael/pro_enabled', false ) ) { |
| 284 | $element->add_control( |
| 285 | 'eael_image_masking_upload_pro_message' . $tab, |
| 286 | [ |
| 287 | 'label' => '', |
| 288 | 'type' => Controls_Manager::RAW_HTML, |
| 289 | 'raw' => '<div class="ea-nerd-box"> |
| 290 | <div class="ea-nerd-box-message">' . __('This feature is available in the pro version.', 'essential-addons-for-elementor-lite') . '</div> |
| 291 | <a class="ea-nerd-box-link elementor-button elementor-button-default" href="https://wpdeveloper.com/upgrade/ea-pro" target="_blank"> |
| 292 | ' . __('Upgrade to EA PRO', 'essential-addons-for-elementor-lite') . ' |
| 293 | </a> |
| 294 | </div>', |
| 295 | 'content_classes' => 'eael-pro-notice', |
| 296 | 'condition' => array_merge( $condition, [ 'eael_image_masking_svg' . $tab => 'upload' ] ) |
| 297 | ] |
| 298 | ); |
| 299 | } else { |
| 300 | do_action( 'eael/image-masking/image_control', $element, array_merge( $condition, [ 'eael_image_masking_svg' . $tab => 'upload' ] ), $tab ); |
| 301 | } |
| 302 | |
| 303 | if( '_hover' === $tab ){ |
| 304 | $element->add_control( |
| 305 | 'eael_image_masking_hover_selector', |
| 306 | [ |
| 307 | 'label' => esc_html__( 'Hover Selector', 'essential-addons-for-elementor-lite' ), |
| 308 | 'type' => Controls_Manager::TEXT, |
| 309 | 'label_block' => true, |
| 310 | 'dynamic' => [ |
| 311 | 'active' => false, |
| 312 | ], |
| 313 | 'ai' => [ |
| 314 | 'active' => true, |
| 315 | ], |
| 316 | 'placeholder' => '.not-masked-element, #not-masked-element', |
| 317 | 'description' => __( 'Enter the selector for the element you want to apply the hover effect on. If you leave this field empty, the hover effect will be applied on hover for full section.', 'essential-addons-for-elementor-lite' ), |
| 318 | 'condition' => [ |
| 319 | 'eael_image_masking_hover_effect' => 'yes', |
| 320 | ] |
| 321 | ] |
| 322 | ); |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | public function register_controls( $element ) { |
| 327 | $element->start_controls_section( |
| 328 | 'eael_image_masking_section', |
| 329 | [ |
| 330 | 'label' => __( '<i class="eaicon-logo"></i> Image Masking', 'essential-addons-for-elementor-lite' ), |
| 331 | 'tab' => Controls_Manager::TAB_ADVANCED |
| 332 | ] |
| 333 | ); |
| 334 | |
| 335 | $element->add_control( |
| 336 | 'eael_enable_image_masking', |
| 337 | [ |
| 338 | 'label' => __( 'Enable Image Masking', 'essential-addons-for-elementor-lite' ), |
| 339 | 'type' => Controls_Manager::SWITCHER |
| 340 | ] |
| 341 | ); |
| 342 | |
| 343 | $element->add_control( |
| 344 | 'eael_image_masking_type', |
| 345 | [ |
| 346 | 'label' => esc_html__( 'Type', 'essential-addons-for-elementor-lite' ), |
| 347 | 'type' => Controls_Manager::CHOOSE, |
| 348 | 'options' => [ |
| 349 | 'image' => [ |
| 350 | 'title' => esc_html__( 'Image/SVG Masking', 'essential-addons-for-elementor-lite' ), |
| 351 | 'icon' => 'eicon-image', |
| 352 | ], |
| 353 | 'clip' => [ |
| 354 | 'title' => esc_html__( 'Clip Path', 'essential-addons-for-elementor-lite' ), |
| 355 | 'icon' => 'eicon-integration', |
| 356 | ], |
| 357 | 'morphing' => [ |
| 358 | 'title' => esc_html__( 'Morphing', 'essential-addons-for-elementor-lite' ), |
| 359 | 'icon' => 'eicon-animation', |
| 360 | ] |
| 361 | ], |
| 362 | 'condition' => [ |
| 363 | 'eael_enable_image_masking' => 'yes' |
| 364 | ], |
| 365 | 'default' => 'clip', |
| 366 | 'toggle' => false, |
| 367 | ] |
| 368 | ); |
| 369 | |
| 370 | $element->start_controls_tabs( 'eael_image_masking_tabs', [ |
| 371 | 'condition' => [ |
| 372 | 'eael_enable_image_masking' => 'yes', |
| 373 | 'eael_image_masking_type!' => 'morphing' |
| 374 | ] |
| 375 | ] ); |
| 376 | |
| 377 | $element->start_controls_tab( |
| 378 | 'eael_image_masking_normal_tab', |
| 379 | [ |
| 380 | 'label' => esc_html__( 'Normal', 'essential-addons-for-elementor-lite' ), |
| 381 | ] |
| 382 | ); |
| 383 | |
| 384 | $this->masking_controllers( $element ); |
| 385 | |
| 386 | $element->end_controls_tab(); |
| 387 | |
| 388 | $element->start_controls_tab( |
| 389 | 'eael_image_masking_hover_tab', |
| 390 | [ |
| 391 | 'label' => esc_html__( 'Hover', 'essential-addons-for-elementor-lite' ), |
| 392 | ] |
| 393 | ); |
| 394 | |
| 395 | $this->masking_controllers( $element, '_hover' ); |
| 396 | |
| 397 | $element->end_controls_tab(); |
| 398 | |
| 399 | $element->end_controls_tabs(); |
| 400 | |
| 401 | $element->add_control( |
| 402 | 'eael_image_masking_image_size', |
| 403 | [ |
| 404 | 'label' => esc_html__( 'Size', 'essential-addons-for-elementor-lite' ), |
| 405 | 'type' => Controls_Manager::SELECT, |
| 406 | 'default' => 'contain', |
| 407 | 'options' => [ |
| 408 | '' => esc_html__( 'Default', 'essential-addons-for-elementor-lite' ), |
| 409 | 'auto' => esc_html__( 'Auto', 'essential-addons-for-elementor-lite' ), |
| 410 | 'cover' => esc_html__( 'Cover', 'essential-addons-for-elementor-lite' ), |
| 411 | 'contain' => esc_html__( 'Contain', 'essential-addons-for-elementor-lite' ), |
| 412 | 'custom' => esc_html__( 'Custom', 'essential-addons-for-elementor-lite' ), |
| 413 | ], |
| 414 | 'condition' => [ |
| 415 | 'eael_enable_image_masking' => 'yes', |
| 416 | 'eael_image_masking_type' => 'image' |
| 417 | ], |
| 418 | 'selectors' => [ |
| 419 | '{{WRAPPER}} img' => 'mask-size: {{VALUE}}; -webkit-mask-size: {{VALUE}};', |
| 420 | ], |
| 421 | ] |
| 422 | ); |
| 423 | |
| 424 | $element->add_control( |
| 425 | 'eael_image_masking_image_custom_size_custom', |
| 426 | [ |
| 427 | 'label' => '', |
| 428 | 'type' => Controls_Manager::SLIDER, |
| 429 | 'size_units' => [ 'px', '%' ], |
| 430 | 'range' => [ |
| 431 | 'px' => [ |
| 432 | 'min' => 0, |
| 433 | 'max' => 1000, |
| 434 | 'step' => 5, |
| 435 | ], |
| 436 | '%' => [ |
| 437 | 'min' => 0, |
| 438 | 'max' => 100, |
| 439 | ], |
| 440 | ], |
| 441 | 'selectors' => [ |
| 442 | '{{WRAPPER}} img' => 'mask-size: {{SIZE}}{{UNIT}}; -webkit-mask-size: {{SIZE}}{{UNIT}};', |
| 443 | ], |
| 444 | 'condition' => [ |
| 445 | 'eael_enable_image_masking' => 'yes', |
| 446 | 'eael_image_masking_type' => 'image', |
| 447 | 'eael_image_masking_image_size' => 'custom' |
| 448 | ], |
| 449 | ] |
| 450 | ); |
| 451 | |
| 452 | $element->add_control( |
| 453 | 'eael_image_masking_image_position', |
| 454 | [ |
| 455 | 'label' => esc_html__( 'Position', 'essential-addons-for-elementor-lite' ), |
| 456 | 'type' => Controls_Manager::SELECT, |
| 457 | 'default' => 'center center', |
| 458 | 'options' => [ |
| 459 | '' => esc_html__( 'Default', 'essential-addons-for-elementor-lite' ), |
| 460 | 'left top' => esc_html__( 'Left Top', 'essential-addons-for-elementor-lite' ), |
| 461 | 'left center' => esc_html__( 'Left Center', 'essential-addons-for-elementor-lite' ), |
| 462 | 'left bottom' => esc_html__( 'Left Bottom', 'essential-addons-for-elementor-lite' ), |
| 463 | 'center top' => esc_html__( 'Center Top', 'essential-addons-for-elementor-lite' ), |
| 464 | 'center center' => esc_html__( 'Center Center', 'essential-addons-for-elementor-lite' ), |
| 465 | 'center bottom' => esc_html__( 'Center Bottom', 'essential-addons-for-elementor-lite' ), |
| 466 | 'right top' => esc_html__( 'Right Top', 'essential-addons-for-elementor-lite' ), |
| 467 | 'right center' => esc_html__( 'Right Center', 'essential-addons-for-elementor-lite' ), |
| 468 | 'right bottom' => esc_html__( 'Right Bottom', 'essential-addons-for-elementor-lite' ) |
| 469 | ], |
| 470 | 'condition' => [ |
| 471 | 'eael_enable_image_masking' => 'yes', |
| 472 | 'eael_image_masking_type' => 'image' |
| 473 | ], |
| 474 | 'selectors' => [ |
| 475 | '{{WRAPPER}} img' => 'mask-position: {{VALUE}}; -webkit-mask-position: {{VALUE}};', |
| 476 | ], |
| 477 | ] |
| 478 | ); |
| 479 | |
| 480 | $element->add_control( |
| 481 | 'eael_image_masking_image_repeat', |
| 482 | [ |
| 483 | 'label' => esc_html__( 'Repeat', 'essential-addons-for-elementor-lite' ), |
| 484 | 'type' => Controls_Manager::SELECT, |
| 485 | 'default' => 'no-repeat', |
| 486 | 'options' => [ |
| 487 | 'no-repeat' => esc_html__( 'No-repeat', 'essential-addons-for-elementor-lite' ), |
| 488 | 'repeat' => esc_html__( 'Repeat', 'essential-addons-for-elementor-lite' ), |
| 489 | 'repeat-x' => esc_html__( 'Repeat-x', 'essential-addons-for-elementor-lite' ), |
| 490 | 'repeat-y' => esc_html__( 'Repeat-y', 'essential-addons-for-elementor-lite' ), |
| 491 | ], |
| 492 | 'condition' => [ |
| 493 | 'eael_enable_image_masking' => 'yes', |
| 494 | 'eael_image_masking_type' => 'image' |
| 495 | ], |
| 496 | 'selectors' => [ |
| 497 | '{{WRAPPER}} img' => 'mask-repeat: {{VALUE}}; -webkit-mask-repeat: {{VALUE}};', |
| 498 | ], |
| 499 | ] |
| 500 | ); |
| 501 | |
| 502 | if ( !apply_filters('eael/pro_enabled', false ) ) { |
| 503 | $element->add_control( |
| 504 | 'eael_image_masking_pro_message', |
| 505 | [ |
| 506 | 'label' => '', |
| 507 | 'type' => Controls_Manager::RAW_HTML, |
| 508 | 'raw' => '<div class="ea-nerd-box"> |
| 509 | <div class="ea-nerd-box-message">' . __('This feature is available in the pro version.', 'essential-addons-for-elementor-lite') . '</div> |
| 510 | <a class="ea-nerd-box-link elementor-button elementor-button-default" href="https://wpdeveloper.com/upgrade/ea-pro" target="_blank"> |
| 511 | ' . __('Upgrade to EA PRO', 'essential-addons-for-elementor-lite') . ' |
| 512 | </a> |
| 513 | </div>', |
| 514 | 'content_classes' => 'eael-pro-notice', |
| 515 | 'condition' => [ |
| 516 | 'eael_enable_image_masking' => 'yes', |
| 517 | 'eael_image_masking_type' => 'morphing' |
| 518 | ] |
| 519 | ] |
| 520 | ); |
| 521 | } else { |
| 522 | do_action( 'eael/image_masking/morphing_controls', $element ); |
| 523 | } |
| 524 | |
| 525 | $element->end_controls_section(); |
| 526 | } |
| 527 | |
| 528 | private function extract_first_path_d($svg) { |
| 529 | // Try DOM first |
| 530 | libxml_use_internal_errors(true); |
| 531 | $dom = new \DOMDocument(); |
| 532 | if (@$dom->loadXML($svg)) { |
| 533 | $path = $dom->getElementsByTagName('path')->item(0); |
| 534 | if ($path) { |
| 535 | return $path->getAttribute('d'); |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | // Regex fallback |
| 540 | if (preg_match('/<path[^>]+d="([^"]+)"/i', $svg, $match)) { |
| 541 | return $match[1]; |
| 542 | } |
| 543 | |
| 544 | return null; // not found |
| 545 | } |
| 546 | public function before_render( $element ) { |
| 547 | $is_enabled = $element->get_settings_for_display( 'eael_enable_image_masking' ); |
| 548 | $settings = $element->get_settings_for_display(); |
| 549 | |
| 550 | if ( 'yes' === $is_enabled ) { |
| 551 | $type = $settings['eael_image_masking_type']; |
| 552 | $element_id = $element->get_id(); |
| 553 | $style = ''; |
| 554 | $element->add_render_attribute( '_wrapper', 'class', 'eael-image-masking-' . esc_attr( $element_id ) ); |
| 555 | if( 'clip' === $type ){ |
| 556 | $clip_path_value = ''; |
| 557 | if( 'yes' === $settings['eael_image_masking_enable_custom_clip_path'] ){ |
| 558 | $clip_path_value = $settings['eael_image_masking_custom_clip_path']; |
| 559 | $clip_path_value = str_replace( 'clip-path: ', '', $clip_path_value ); |
| 560 | } else { |
| 561 | $clip_path = $settings['eael_image_masking_clip_path']; |
| 562 | $clip_path_value = $this->clip_paths( $clip_path ); |
| 563 | } |
| 564 | if( $clip_path_value ) { |
| 565 | $style .= '.eael-image-masking-'. esc_html( $element_id ) .' img {clip-path: '.$clip_path_value.'}'; |
| 566 | } |
| 567 | |
| 568 | if( 'yes' === $settings['eael_image_masking_hover_effect'] ){ |
| 569 | $hover_clip_path_value = ''; |
| 570 | if( 'yes' === $settings['eael_image_masking_enable_custom_clip_path_hover'] ){ |
| 571 | $hover_clip_path_value = $settings['eael_image_masking_custom_clip_path_hover']; |
| 572 | $hover_clip_path_value = str_replace( 'clip-path: ', '', $hover_clip_path_value ); |
| 573 | } else { |
| 574 | $hover_clip_path = $settings['eael_image_masking_clip_path_hover']; |
| 575 | $hover_clip_path_value = $this->clip_paths( $hover_clip_path ); |
| 576 | } |
| 577 | if( $hover_clip_path_value ) { |
| 578 | $hover_selector = $settings['eael_image_masking_hover_selector']; |
| 579 | if( $hover_selector ){ |
| 580 | $hover_selector = ' ' . trim( $hover_selector ); |
| 581 | } |
| 582 | $style .= '.eael-image-masking-'. esc_html( $element_id ) . $hover_selector . ':hover img {clip-path: '.$hover_clip_path_value.'}'; |
| 583 | } |
| 584 | } |
| 585 | } else if( 'image' === $type ) { |
| 586 | $svg = $element->get_settings_for_display( 'eael_image_masking_svg' ); |
| 587 | $mask_url = ''; |
| 588 | if( 'upload' !== $svg ){ |
| 589 | $svg_url = self::$svg_dir_url; |
| 590 | $mask_url = $svg_url . $svg . '.svg'; |
| 591 | } else if( 'upload' === $svg ){ |
| 592 | $image = $element->get_settings_for_display( 'eael_image_masking_image' ); |
| 593 | $mask_url = isset( $image['url'] ) ? $image['url'] : ''; |
| 594 | } |
| 595 | |
| 596 | if( $mask_url ) { |
| 597 | $style .= '.eael-image-masking-'. esc_html( $element_id ) .' img {mask-image: url('.$mask_url.'); -webkit-mask-image: url('.$mask_url.');}'; |
| 598 | } |
| 599 | |
| 600 | if( 'yes' === $settings['eael_image_masking_hover_effect'] ){ |
| 601 | $hover_image = $element->get_settings_for_display( 'eael_image_masking_svg_hover' ); |
| 602 | $hover_mask_url = ''; |
| 603 | if( 'upload' !== $hover_image ){ |
| 604 | $svg = $element->get_settings_for_display( 'eael_image_masking_svg' ); |
| 605 | $svg_url = self::$svg_dir_url; |
| 606 | $hover_mask_url = $svg_url . $hover_image . '.svg'; |
| 607 | } else if( 'upload' === $hover_image ){ |
| 608 | $hover_image = $element->get_settings_for_display( 'eael_image_masking_image_hover' ); |
| 609 | $hover_mask_url = $hover_image['url'] ?? ''; |
| 610 | } |
| 611 | if( $hover_mask_url ) { |
| 612 | $hover_selector = $element->get_settings_for_display( 'eael_image_masking_hover_selector' ); |
| 613 | if( $hover_selector ){ |
| 614 | $hover_selector = ' ' . trim( $hover_selector ); |
| 615 | } |
| 616 | $style .= '.eael-image-masking-'. esc_html( $element_id ) . $hover_selector .':hover img {mask-image: url('.$hover_mask_url.'); -webkit-mask-image: url('.$hover_mask_url.');}'; |
| 617 | } |
| 618 | } |
| 619 | |
| 620 | } else if( 'morphing' === $type ) { |
| 621 | $morphing_options = apply_filters( 'eael/image_masking/morphing_options', [], $element, $element_id ); |
| 622 | if( !empty( $morphing_options ) ){ |
| 623 | if( !empty( $morphing_options['svg_html'] ) ){ |
| 624 | //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 625 | echo $morphing_options['svg_html']; |
| 626 | } |
| 627 | unset( $morphing_options['svg_html'] ); |
| 628 | $element->add_render_attribute( '_wrapper', 'data-morphing-options', wp_json_encode( $morphing_options ) ); |
| 629 | $element->add_render_attribute( '_wrapper', 'class', 'eael-morphing-enabled' ); |
| 630 | } |
| 631 | } |
| 632 | |
| 633 | |
| 634 | if( $style ){ |
| 635 | //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 636 | echo '<style id="eael-image-masking-'. esc_attr( $element_id ) .'">'. $style .'</style>'; |
| 637 | } |
| 638 | } |
| 639 | } |
| 640 | } |