PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.14.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.14.0
2.14.0 2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 All 81 releases
← All changes | includes/blocks/image-hotspot/block.php +424 -0 2.7.4 → 2.14.0 View file →
@@ -1,0 +1,424 @@
1 +<?php
2 +namespace ABlocks\Blocks\ImageHotspot;
3 +
4 +use ABlocks\Controls\Range;
5 +use ABlocks\Controls\Color;
6 +
7 +if ( ! defined( 'ABSPATH' ) ) {
8 + exit;
9 +}
10 +
11 +use ABlocks\Classes\BlockBaseAbstract;
12 +use ABlocks\Classes\CssGenerator;
13 +use ABlocks\Controls\BoxShadow;
14 +use ABlocks\Classes\CssGeneratorV2;
15 +
16 +
17 +class Block extends BlockBaseAbstract {
18 + protected $block_name = 'image-hotspot';
19 +
20 + public function build_css_v1( $attributes ) {
21 + $css_generator = new CssGenerator( $attributes, $this->block_name );
22 +
23 + $css_generator->add_class_styles(
24 + '{{WRAPPER}} .ablocks-image-hotspot__pin:after',
25 + [
26 + 'animation' => $attributes['animationType'],
27 + ]
28 + );
29 +
30 + // Loop through lists and apply styles for each pin
31 + if ( ! empty( $attributes['lists'] ) ) {
32 + foreach ( $attributes['lists'] as $list ) {
33 + $css_generator->add_class_styles(
34 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}",
35 + $this->get_pin_css( $attributes, $list )
36 + );
37 +
38 + $css_generator->add_class_styles(
39 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:after",
40 + $this->get_pin_effect_css( $attributes, $list )
41 + );
42 +
43 + $css_generator->add_class_styles(
44 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:hover",
45 + $this->get_pin_hover_css( $attributes, $list )
46 + );
47 +
48 + $css_generator->add_class_styles(
49 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:hover:after",
50 + $this->get_pin_hover_effect_css( $attributes, $list )
51 + );
52 + }//end foreach
53 + }//end if
54 +
55 + if ( $this->has_pin_icon( $attributes ) ) {
56 + $css_generator->add_class_styles(
57 + '{{WRAPPER}} .ablocks-image-hotspot__pin--has-icon .ablocks-icon-wrap',
58 + $this->get_pin_icon_css( $attributes )
59 + );
60 + $css_generator->add_class_styles(
61 + '{{WRAPPER}} .ablocks-image-hotspot__pin--has-icon .ablocks-icon-wrap svg.ablocks-svg-icon',
62 + $this->get_pin_icon_svg_css( $attributes )
63 + );
64 + }
65 +
66 + // Tooltip content animation
67 + $css_generator->add_class_styles(
68 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip-content',
69 + $this->get_tooltip_content_css( $attributes )
70 + );
71 +
72 + $css_generator->add_class_styles(
73 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip--active',
74 + $this->get_active_content_css( $attributes ),
75 + $this->get_active_content_css( $attributes, 'Tablet' ),
76 + $this->get_active_content_css( $attributes, 'Mobile' ),
77 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_active_content_css( $attributes, $device ); } )
78 + );
79 +
80 + $css_generator->add_class_styles(
81 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip--active:hover',
82 + $this->get_active_content_hover_css( $attributes ),
83 + $this->get_active_content_hover_css( $attributes, 'Tablet' ),
84 + $this->get_active_content_hover_css( $attributes, 'Mobile' ),
85 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_active_content_hover_css( $attributes, $device ); } )
86 + );
87 +
88 + return $css_generator->generate_css();
89 + }
90 + public function build_css_v2( $attributes ) {
91 + $css_generator = new CssGeneratorV2( $attributes, $this->block_name );
92 +
93 + $css_generator->add_class_styles(
94 + '{{WRAPPER}} .ablocks-image-hotspot__pin:after',
95 + [
96 + 'animation' => $attributes['animationType'],
97 + ]
98 + );
99 +
100 + // Loop through lists and apply styles for each pin
101 + if ( ! empty( $attributes['lists'] ) ) {
102 + foreach ( $attributes['lists'] as $list ) {
103 + $css_generator->add_class_styles(
104 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}",
105 + $this->get_pin_css( $attributes, $list )
106 + );
107 +
108 + $css_generator->add_class_styles(
109 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:after",
110 + $this->get_pin_effect_css( $attributes, $list )
111 + );
112 +
113 + $css_generator->add_class_styles(
114 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:hover",
115 + $this->get_pin_hover_css( $attributes, $list )
116 + );
117 +
118 + $css_generator->add_class_styles(
119 + "{{WRAPPER}} .ablocks-image-hotspot-list-{$list['id']}:hover:after",
120 + $this->get_pin_hover_effect_css( $attributes, $list )
121 + );
122 + }//end foreach
123 + }//end if
124 +
125 + if ( $this->has_pin_icon( $attributes ) ) {
126 + $css_generator->add_class_styles(
127 + '{{WRAPPER}} .ablocks-image-hotspot__pin--has-icon .ablocks-icon-wrap',
128 + $this->get_pin_icon_css( $attributes )
129 + );
130 + $css_generator->add_class_styles(
131 + '{{WRAPPER}} .ablocks-image-hotspot__pin--has-icon .ablocks-icon-wrap svg.ablocks-svg-icon',
132 + $this->get_pin_icon_svg_css( $attributes )
133 + );
134 + }
135 +
136 + // Tooltip content animation
137 + $css_generator->add_class_styles(
138 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip-content',
139 + $this->get_tooltip_content_css( $attributes )
140 + );
141 +
142 + $css_generator->add_class_styles(
143 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip--active',
144 + $this->get_active_content_css( $attributes ),
145 + $this->get_active_content_css( $attributes, 'Tablet' ),
146 + $this->get_active_content_css( $attributes, 'Mobile' ),
147 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_active_content_css( $attributes, $device ); } )
148 + );
149 +
150 + $css_generator->add_class_styles(
151 + '{{WRAPPER}} .ablocks-image-hotspot__tooltip--active:hover',
152 + $this->get_active_content_hover_css( $attributes ),
153 + $this->get_active_content_hover_css( $attributes, 'Tablet' ),
154 + $this->get_active_content_hover_css( $attributes, 'Mobile' ),
155 + $css_generator->custom_device_map( function ( $device ) use ( $attributes ) { return $this->get_active_content_hover_css( $attributes, $device ); } )
156 + );
157 +
158 + return $css_generator->generate_css();
159 + }
160 + public function build_css( $attributes ) {
161 + if ( isset( $attributes['blockVersion'] ) && (int) $attributes['blockVersion'] === 2 ) {
162 + return $this->build_css_v2( $attributes );
163 + }
164 + return $this->build_css_v1( $attributes );
165 + }
166 + // Mirrors hasHotspotIcon() in the editor: a removed icon keeps iconClass 'Empty'.
167 + public function has_pin_icon( $attributes ) {
168 + foreach ( $attributes['lists'] ?? [] as $list ) {
169 + $icon = $list['icon'] ?? [];
170 + if ( ( $icon['iconClass'] ?? '' ) !== 'Empty' && ( ! empty( $icon['iconSvgPath'] ) || ! empty( $icon['iconImageUrl'] ) ) ) {
171 + return true;
172 + }
173 + }
174 + return false;
175 + }
176 + public function get_pin_icon_css( $attributes ) {
177 + $css = [];
178 + if ( ! empty( $attributes['pinIconSize'] ) ) {
179 + $css['width'] = $attributes['pinIconSize'] . '%';
180 + $css['height'] = $attributes['pinIconSize'] . '%';
181 + }
182 + return $css;
183 + }
184 + public function get_pin_icon_svg_css( $attributes ) {
185 + $css = [];
186 + if ( ! empty( $attributes['pinIconColor'] ) ) {
187 + $css['fill'] = Color::get_css( $attributes['pinIconColor'] );
188 + }
189 + return $css;
190 + }
191 + public function get_pin_css( $attributes, $list ) {
192 + return [
193 + 'background-color' => Color::get_css( ! empty( $list['pinColorEffect'] ) ? $list['pinColorEffect'] : $attributes['pinColorEffect'] ),
194 + 'width' => ! empty( $list['pinSize'] ) ? $list['pinSize'] . 'px' : $attributes['pinSize'] . 'px',
195 + 'height' => ! empty( $list['pinSize'] ) ? $list['pinSize'] . 'px' : $attributes['pinSize'] . 'px',
196 + 'transform' => 'translate(-50%, -50%)',
197 + ];
198 + }
199 +
200 + public function get_pin_effect_css( $attributes, $list ) {
201 + return [
202 + 'background-color' => Color::get_css( ! empty( $list['pinColor'] ) ? $list['pinColor'] : $attributes['pinColor'] ),
203 + 'width' => ! empty( $list['pinSize'] ) ? $list['pinSize'] . 'px' : $attributes['pinSize'] . 'px',
204 + 'height' => ! empty( $list['pinSize'] ) ? $list['pinSize'] . 'px' : $attributes['pinSize'] . 'px',
205 + ];
206 + }
207 +
208 + public function get_pin_hover_css( $attributes, $list ) {
209 + return [
210 + 'background-color' => Color::get_css( ! empty( $list['pinHoverColor'] ) ? $list['pinHoverColor'] : $attributes['pinHoverColor'] ),
211 + 'transform' => 'translate(-50%, -50%)',
212 + '--ablocks-hotspot-effect-max-scale' => ! empty( $list['pinHoverSize'] ) ? $list['pinHoverSize'] : $attributes['pinHoverSize'],
213 + ];
214 + }
215 +
216 + public function get_pin_hover_effect_css( $attributes, $list ) {
217 + return [
218 + 'background-color' => Color::get_css( ! empty( $list['pinHoverColor'] ) ? $list['pinHoverColor'] : $attributes['pinHoverColor'] ),
219 + '--ablocks-hotspot-effect-max-scale' => ! empty( $list['pinHoverSize'] ) ? $list['pinHoverSize'] : $attributes['pinHoverSize'],
220 + ];
221 + }
222 +
223 + public function get_tooltip_content_css( $attributes ) {
224 + // Extract the attributes
225 + $content_position = $attributes['contentPosition'];
226 + $content_animation = $attributes['contentAnimation'];
227 +
228 + // Initialize transform values for sliding animations
229 + $translateX_start = '0px';
230 + $translateY_start = '0px';
231 + $translateX_end = '-50%';
232 + $translateY_end = '0px';
233 +
234 + // Default transform for bottom position
235 + $content_transform = 'translate(-50%, 40px)';
236 +
237 + if ( $content_position === 'top' ) {
238 + $content_transform = 'translate(-50%, calc(-100% - 40px))';
239 + } elseif ( $content_position === 'left' ) {
240 + $content_transform = 'translate(calc(-100% - 40px), -50%)';
241 + } elseif ( $content_position === 'right' ) {
242 + $content_transform = 'translate(40px, -50%)';
243 + }
244 +
245 + // Set default animation duration and ease if not provided
246 + $animation_duration = '0.5s';
247 + $animation_ease = 'ease';
248 +
249 + // Set animation style dynamically based on contentAnimation
250 + $animation_style = '';
251 + if ( $content_animation === 'ablocks-hotspot-fadeIn' ) {
252 + $animation_style = 'ablocks-hotspot-fadeIn 1.0s ease forwards';
253 + } elseif ( $content_animation === 'ablocks-hotspot-fadeGrow' ) {
254 + $animation_style = 'ablocks-hotspot-fadeGrow 0.5s ease';
255 + switch ( $content_position ) {
256 + case 'top':
257 + $translateX_end = '-50%';
258 + $translateY_end = 'calc(-100% - 40px)';
259 + $translateX_start = $translateX_end;
260 + $translateY_start = $translateY_end;
261 + break;
262 + case 'bottom':
263 + $translateX_end = '-50%';
264 + $translateY_end = '40px';
265 + $translateX_start = $translateX_end;
266 + $translateY_start = $translateY_end;
267 + break;
268 + case 'left':
269 + $translateX_end = 'calc(-100% - 40px)';
270 + $translateY_end = '-50%';
271 + $translateX_start = $translateX_end;
272 + $translateY_start = $translateY_end;
273 + break;
274 + case 'right':
275 + $translateX_end = '40px';
276 + $translateY_end = '-50%';
277 + $translateX_start = $translateX_end;
278 + $translateY_start = $translateY_end;
279 + break;
280 + }//end switch
281 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
282 + } elseif ( in_array( $content_animation, [ 'ablocks-hotspot-slideInTop', 'ablocks-hotspot-slideInBottom', 'ablocks-hotspot-slideInLeft', 'ablocks-hotspot-slideInRight' ] ) ) {
283 + $animation_style = "ablocks-hotspot-slideIn {$animation_duration} {$animation_ease} forwards";
284 + }//end if
285 +
286 + // Handle specific sliding animations per position
287 + switch ( $content_position ) {
288 + case 'top':
289 + $translateX_end = '-50%';
290 + $translateY_end = 'calc(-100% - 40px)';
291 + $translateX_start = $translateX_end;
292 + $translateY_start = $translateY_end;
293 +
294 + switch ( $content_animation ) {
295 + case 'ablocks-hotspot-slideInLeft':
296 + $translateX_start = 'calc(-50% - 40px)';
297 + break;
298 + case 'ablocks-hotspot-slideInRight':
299 + $translateX_start = 'calc(-50% + 40px)';
300 + break;
301 + case 'ablocks-hotspot-slideInTop':
302 + $translateY_start = 'calc(-100% - 60px)';
303 + break;
304 + case 'ablocks-hotspot-slideInBottom':
305 + $translateY_start = 'calc(-100% + 40px)';
306 + break;
307 + }
308 + break;
309 +
310 + case 'bottom':
311 + $translateX_end = '-50%';
312 + $translateY_end = '40px';
313 + $translateX_start = $translateX_end;
314 + $translateY_start = $translateY_end;
315 +
316 + switch ( $content_animation ) {
317 + case 'ablocks-hotspot-slideInLeft':
318 + $translateX_start = 'calc(-50% - 40px)';
319 + break;
320 + case 'ablocks-hotspot-slideInRight':
321 + $translateX_start = 'calc(-50% + 40px)';
322 + break;
323 + case 'ablocks-hotspot-slideInTop':
324 + $translateY_start = 'calc(40px - 40px)';
325 + break;
326 + case 'ablocks-hotspot-slideInBottom':
327 + $translateY_start = 'calc(40px + 40px)';
328 + break;
329 + }
330 + break;
331 +
332 + case 'left':
333 + $translateX_end = 'calc(-100% - 40px)';
334 + $translateY_end = '-50%';
335 + $translateX_start = $translateX_end;
336 + $translateY_start = $translateY_end;
337 +
338 + switch ( $content_animation ) {
339 + case 'ablocks-hotspot-slideInLeft':
340 + $translateX_start = 'calc(-100% - 40px - 40px)';
341 + break;
342 + case 'ablocks-hotspot-slideInRight':
343 + $translateX_start = 'calc(-100% - 40px + 40px)';
344 + break;
345 + case 'ablocks-hotspot-slideInTop':
346 + $translateY_start = 'calc(-50% - 40px)';
347 + break;
348 + case 'ablocks-hotspot-slideInBottom':
349 + $translateY_start = 'calc(-50% + 40px)';
350 + break;
351 + }
352 + break;
353 +
354 + case 'right':
355 + $translateX_end = '40px';
356 + $translateY_end = '-50%';
357 + $translateX_start = $translateX_end;
358 + $translateY_start = $translateY_end;
359 +
360 + switch ( $content_animation ) {
361 + case 'ablocks-hotspot-slideInLeft':
362 + $translateX_start = 'calc(40px - 40px)';
363 + break;
364 + case 'ablocks-hotspot-slideInRight':
365 + $translateX_start = 'calc(40px + 40px)';
366 + break;
367 + case 'ablocks-hotspot-slideInTop':
368 + $translateY_start = 'calc(-50% - 40px)';
369 + break;
370 + case 'ablocks-hotspot-slideInBottom':
371 + $translateY_start = 'calc(-50% + 40px)';
372 + break;
373 + }
374 + break;
375 + }//end switch
376 +
377 + // Return the final styles as an array
378 + return [
379 + 'animation' => $animation_style,
380 + 'transform' => $content_transform,
381 + '--ablocks-hotspot-translateX-start' => $translateX_start,
382 + '--ablocks-hotspot-translateY-start' => $translateY_start,
383 + '--ablocks-hotspot-translateX-end' => $translateX_end,
384 + '--ablocks-hotspot-translateY-end' => $translateY_end,
385 + ];
386 + }
387 +
388 + public function get_active_content_css( $attributes, $device = '' ) {
389 + $css = array();
390 + if ( isset( $width[ 'value' . $device ] ) && ! empty( $width[ 'value' . $device ] ) ) {
391 +
392 + if ( ! empty( $width[ 'valueUnit' . $device ] ) ) {
393 + $css['width'] = $width[ 'value' . $device ] . $width[ 'valueUnit' . $device ];
394 + } else {
395 + $css['width'] = $width[ 'value' . $device ] . 'px';
396 + }
397 + }
398 +
399 + $css = array_merge(
400 + [ 'background' => Color::get_css( isset( $attributes['backgroundColor'] ) ? $attributes['backgroundColor'] : '' ) ],
401 + $css,
402 + Range::get_css([
403 + 'attributeValue' => $attributes['childWidth'],
404 + 'attribute_object_key' => 'value',
405 + 'isResponsive' => true,
406 + 'defaultValue' => 200,
407 + 'hasUnit' => true,
408 + 'unitDefaultValue' => 'px',
409 + 'property' => 'width',
410 + 'device' => $device,
411 + ]),
412 + isset( $attributes['commonBoxShadow'] ) ? BoxShadow::get_css( $attributes['commonBoxShadow'], '', $device ) : [] );
413 +
414 + return $css;
415 + }
416 +
417 + public function get_active_content_hover_css( $attributes, $device = '' ) {
418 +
419 + $css = isset( $attributes['commonBoxShadow'] ) ? BoxShadow::get_hover_css( $attributes['commonBoxShadow'], '', $device ) : [];
420 +
421 + return $css;
422 + }
423 +
424 +}