Animations.php
1 month ago
BackButton.php
7 months ago
BeforeAfter.php
1 month ago
BlockPatterns.php
4 months ago
Carousel.php
1 month ago
ContainerEdgeAlignment.php
1 month ago
Counter.php
1 month ago
Events.php
6 months ago
FaqSchema.php
1 month ago
FluidTypography.php
4 months ago
Gallery.php
8 months ago
GravityFormsInline.php
1 month ago
Headline.php
1 month ago
InsertPost.php
1 month ago
ProductCategories.php
8 months ago
ReadingProgress.php
7 months ago
ReadingTime.php
8 months ago
ShapeAnimations.php
1 month ago
StackedImages.php
4 months ago
StickyColumn.php
1 month ago
Testimonials.php
8 months ago
TextAnimation.php
1 month ago
StackedImages.php
190 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Stacked Images module for FrontBlocks. |
| 4 | * |
| 5 | * @package FrontBlocks |
| 6 | * @author David Perez <david@close.technology> |
| 7 | * @copyright 2025 Closemarketing |
| 8 | * @version 1.0 |
| 9 | */ |
| 10 | |
| 11 | namespace FrontBlocks\Frontend; |
| 12 | |
| 13 | use WP_Block_Type_Registry; |
| 14 | |
| 15 | defined( 'ABSPATH' ) || exit; |
| 16 | |
| 17 | /** |
| 18 | * StackedImages class. |
| 19 | * |
| 20 | * @since 1.0.0 |
| 21 | */ |
| 22 | class StackedImages { |
| 23 | |
| 24 | /** |
| 25 | * Constructor. |
| 26 | */ |
| 27 | public function __construct() { |
| 28 | add_action( 'init', array( $this, 'register_stacked_images_block' ), 20 ); |
| 29 | add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) ); |
| 30 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_scripts' ) ); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * Enqueue frontend scripts and styles. |
| 35 | * |
| 36 | * @return void |
| 37 | */ |
| 38 | public function enqueue_frontend_scripts() { |
| 39 | wp_register_style( |
| 40 | 'frontblocks-stacked-images-style', |
| 41 | FRBL_PLUGIN_URL . 'assets/stacked-images/frontblocks-stacked-images.css', |
| 42 | array(), |
| 43 | FRBL_VERSION |
| 44 | ); |
| 45 | |
| 46 | wp_register_script( |
| 47 | 'frontblocks-stacked-images-frontend', |
| 48 | FRBL_PLUGIN_URL . 'assets/stacked-images/frontblocks-stacked-images-frontend.js', |
| 49 | array(), |
| 50 | FRBL_VERSION, |
| 51 | true |
| 52 | ); |
| 53 | |
| 54 | if ( is_admin() || has_block( 'frontblocks/stacked-images' ) ) { |
| 55 | wp_enqueue_style( 'frontblocks-stacked-images-style' ); |
| 56 | wp_enqueue_script( 'frontblocks-stacked-images-frontend' ); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * Enqueue block editor assets. |
| 62 | * |
| 63 | * @return void |
| 64 | */ |
| 65 | public function enqueue_block_editor_assets() { |
| 66 | // Enqueue styles for editor. |
| 67 | wp_enqueue_style( |
| 68 | 'frontblocks-stacked-images-style', |
| 69 | FRBL_PLUGIN_URL . 'assets/stacked-images/frontblocks-stacked-images.css', |
| 70 | array(), |
| 71 | FRBL_VERSION |
| 72 | ); |
| 73 | |
| 74 | wp_enqueue_script( |
| 75 | 'frontblocks-stacked-images-option', |
| 76 | FRBL_PLUGIN_URL . 'assets/stacked-images/frontblocks-stacked-images.js', |
| 77 | array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-data', 'wp-editor', 'wp-block-editor', 'wp-compose', 'wp-i18n' ), |
| 78 | FRBL_VERSION, |
| 79 | true |
| 80 | ); |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * Register the Stacked Images block. |
| 85 | * |
| 86 | * @return void |
| 87 | */ |
| 88 | public function register_stacked_images_block() { |
| 89 | if ( ! function_exists( 'register_block_type' ) ) { |
| 90 | return; |
| 91 | } |
| 92 | |
| 93 | $args = array( |
| 94 | 'editor_script' => 'frontblocks-stacked-images-option', |
| 95 | 'render_callback' => array( $this, 'render_stacked_images_block' ), |
| 96 | 'attributes' => array( |
| 97 | 'images' => array( |
| 98 | 'type' => 'array', |
| 99 | 'default' => array(), |
| 100 | ), |
| 101 | 'direction' => array( |
| 102 | 'type' => 'string', |
| 103 | 'default' => 'bottom', |
| 104 | ), |
| 105 | 'animationDuration' => array( |
| 106 | 'type' => 'number', |
| 107 | 'default' => 1000, |
| 108 | ), |
| 109 | 'animationDelay' => array( |
| 110 | 'type' => 'number', |
| 111 | 'default' => 500, |
| 112 | ), |
| 113 | 'containerHeight' => array( |
| 114 | 'type' => 'number', |
| 115 | 'default' => 500, |
| 116 | ), |
| 117 | 'className' => array( |
| 118 | 'type' => 'string', |
| 119 | 'default' => '', |
| 120 | ), |
| 121 | ), |
| 122 | ); |
| 123 | |
| 124 | if ( ! WP_Block_Type_Registry::get_instance()->is_registered( 'frontblocks/stacked-images' ) ) { |
| 125 | register_block_type( |
| 126 | 'frontblocks/stacked-images', |
| 127 | $args |
| 128 | ); |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | /** |
| 133 | * Render the Stacked Images block on frontend. |
| 134 | * |
| 135 | * @param array $attributes Block attributes. |
| 136 | * @return string HTML output. |
| 137 | */ |
| 138 | public function render_stacked_images_block( $attributes ) { |
| 139 | $images = $attributes['images'] ?? array(); |
| 140 | $direction = sanitize_text_field( $attributes['direction'] ?? 'bottom' ); |
| 141 | $animation_duration = absint( $attributes['animationDuration'] ?? 1000 ); |
| 142 | $animation_delay = absint( $attributes['animationDelay'] ?? 500 ); |
| 143 | $container_height = absint( $attributes['containerHeight'] ?? 500 ); |
| 144 | |
| 145 | if ( empty( $images ) ) { |
| 146 | return '<div class="frbl-stacked-images-placeholder">' . esc_html__( 'Please add images to the Stacked Images block.', 'frontblocks' ) . '</div>'; |
| 147 | } |
| 148 | |
| 149 | $wrapper_class = 'frbl-stacked-images-wrapper'; |
| 150 | if ( ! empty( $attributes['className'] ) ) { |
| 151 | $wrapper_class .= ' ' . esc_attr( $attributes['className'] ); |
| 152 | } |
| 153 | |
| 154 | ob_start(); |
| 155 | ?> |
| 156 | <div |
| 157 | class="<?php echo esc_attr( $wrapper_class ); ?>" |
| 158 | data-direction="<?php echo esc_attr( $direction ); ?>" |
| 159 | data-duration="<?php echo esc_attr( $animation_duration ); ?>" |
| 160 | data-delay="<?php echo esc_attr( $animation_delay ); ?>" |
| 161 | style="height: <?php echo esc_attr( $container_height ); ?>px;" |
| 162 | > |
| 163 | <div class="frbl-stacked-images-container"> |
| 164 | <?php foreach ( $images as $index => $image ) : ?> |
| 165 | <?php |
| 166 | $image_url = isset( $image['url'] ) ? $image['url'] : ''; |
| 167 | $image_alt = isset( $image['alt'] ) ? $image['alt'] : ''; |
| 168 | $image_id = isset( $image['id'] ) ? absint( $image['id'] ) : 0; |
| 169 | ?> |
| 170 | <div |
| 171 | class="frbl-stacked-image" |
| 172 | data-index="<?php echo esc_attr( $index ); ?>" |
| 173 | style="z-index: <?php echo esc_attr( $index + 1 ); ?>;" |
| 174 | > |
| 175 | <img |
| 176 | src="<?php echo esc_url( $image_url ); ?>" |
| 177 | alt="<?php echo esc_attr( $image_alt ); ?>" |
| 178 | loading="lazy" |
| 179 | /> |
| 180 | </div> |
| 181 | <?php endforeach; ?> |
| 182 | </div> |
| 183 | </div> |
| 184 | <?php |
| 185 | return ob_get_clean(); |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | new StackedImages(); |
| 190 |