PluginProbe ʕ •ᴥ•ʔ
FrontBlocks for Gutenberg/GeneratePress / ci-artifacts
FrontBlocks for Gutenberg/GeneratePress vci-artifacts
trunk 0.2.0 0.2.1 0.2.2 0.2.3 0.2.4 0.2.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 ci-artifacts
frontblocks / includes / Frontend / BeforeAfter.php
frontblocks / includes / Frontend Last commit date
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
BeforeAfter.php
214 lines
1 <?php
2 /**
3 * Before After Block module for FrontBlocks.
4 *
5 * @package FrontBlocks
6 * @author Closemarketing
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 * BeforeAfter class.
19 *
20 * @since 1.0.0
21 */
22 class BeforeAfter {
23
24 /**
25 * Constructor.
26 */
27 public function __construct() {
28 add_action( 'init', array( $this, 'register_before_after_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-before-after-style',
41 FRBL_PLUGIN_URL . 'assets/before-after/frontblocks-before-after.css',
42 array(),
43 FRBL_VERSION
44 );
45
46 wp_register_script(
47 'frontblocks-before-after-frontend',
48 FRBL_PLUGIN_URL . 'assets/before-after/frontblocks-before-after-frontend.js',
49 array(),
50 FRBL_VERSION,
51 true
52 );
53
54 if ( is_admin() || has_block( 'frontblocks/before-after' ) ) {
55 wp_enqueue_style( 'frontblocks-before-after-style' );
56 wp_enqueue_script( 'frontblocks-before-after-frontend' );
57 }
58 }
59
60 /**
61 * Enqueue block editor assets.
62 *
63 * @return void
64 */
65 public function enqueue_block_editor_assets() {
66 wp_enqueue_style(
67 'frontblocks-before-after-style',
68 FRBL_PLUGIN_URL . 'assets/before-after/frontblocks-before-after.css',
69 array(),
70 FRBL_VERSION
71 );
72
73 wp_enqueue_script(
74 'frontblocks-before-after-option',
75 FRBL_PLUGIN_URL . 'assets/before-after/frontblocks-before-after.js',
76 array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-i18n' ),
77 FRBL_VERSION,
78 true
79 );
80 }
81
82 /**
83 * Register the Before After block.
84 *
85 * @return void
86 */
87 public function register_before_after_block() {
88 if ( ! function_exists( 'register_block_type' ) ) {
89 return;
90 }
91
92 $args = array(
93 'editor_script' => 'frontblocks-before-after-option',
94 'render_callback' => array( $this, 'render_before_after_block' ),
95 'attributes' => array(
96 'beforeImageId' => array(
97 'type' => 'integer',
98 ),
99 'beforeImageUrl' => array(
100 'type' => 'string',
101 'default' => '',
102 ),
103 'afterImageId' => array(
104 'type' => 'integer',
105 ),
106 'afterImageUrl' => array(
107 'type' => 'string',
108 'default' => '',
109 ),
110 'beforeLabel' => array(
111 'type' => 'string',
112 'default' => 'Before',
113 ),
114 'afterLabel' => array(
115 'type' => 'string',
116 'default' => 'After',
117 ),
118 'initialPosition' => array(
119 'type' => 'number',
120 'default' => 50,
121 ),
122 'fixedHeight' => array(
123 'type' => 'boolean',
124 'default' => false,
125 ),
126 'blockHeight' => array(
127 'type' => 'number',
128 'default' => 400,
129 ),
130 ),
131 );
132
133 if ( ! WP_Block_Type_Registry::get_instance()->is_registered( 'frontblocks/before-after' ) ) {
134 register_block_type( 'frontblocks/before-after', $args );
135 }
136 }
137
138 /**
139 * Render the Before After block on the frontend.
140 *
141 * @param array $attributes Block attributes.
142 * @return string HTML output.
143 */
144 public function render_before_after_block( $attributes ) {
145 $before_url = isset( $attributes['beforeImageUrl'] ) ? $attributes['beforeImageUrl'] : '';
146 $after_url = isset( $attributes['afterImageUrl'] ) ? $attributes['afterImageUrl'] : '';
147
148 if ( empty( $before_url ) || empty( $after_url ) ) {
149 return '';
150 }
151
152 $initial_position = isset( $attributes['initialPosition'] ) ? (int) $attributes['initialPosition'] : 50;
153 $before_label = isset( $attributes['beforeLabel'] ) ? $attributes['beforeLabel'] : __( 'Before', 'frontblocks' );
154 $after_label = isset( $attributes['afterLabel'] ) ? $attributes['afterLabel'] : __( 'After', 'frontblocks' );
155
156 $fixed_height = ! empty( $attributes['fixedHeight'] );
157 $block_height = isset( $attributes['blockHeight'] ) ? (int) $attributes['blockHeight'] : 400;
158
159 $wrapper_class = 'frbl-before-after';
160 if ( $fixed_height ) {
161 $wrapper_class .= ' frbl-before-after--fixed-height';
162 }
163 if ( ! empty( $attributes['className'] ) ) {
164 $wrapper_class .= ' ' . esc_attr( $attributes['className'] );
165 }
166
167 $wrapper_style = $fixed_height && $block_height ? ' style="height:' . esc_attr( $block_height ) . 'px"' : '';
168
169 ob_start();
170 ?>
171 <div
172 class="<?php echo esc_attr( $wrapper_class ); ?>"
173 data-initial-position="<?php echo esc_attr( $initial_position ); ?>"
174 <?php echo $wrapper_style; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
175 >
176 <div class="frbl-before-after__after">
177 <img src="<?php echo esc_url( $after_url ); ?>" alt="" loading="lazy">
178 <?php if ( ! empty( $after_label ) ) : ?>
179 <span class="frbl-before-after__label frbl-before-after__label--after">
180 <?php echo wp_kses_post( $after_label ); ?>
181 </span>
182 <?php endif; ?>
183 </div>
184 <div class="frbl-before-after__before">
185 <img src="<?php echo esc_url( $before_url ); ?>" alt="" loading="lazy">
186 <?php if ( ! empty( $before_label ) ) : ?>
187 <span class="frbl-before-after__label frbl-before-after__label--before">
188 <?php echo wp_kses_post( $before_label ); ?>
189 </span>
190 <?php endif; ?>
191 </div>
192 <div
193 class="frbl-before-after__handle"
194 role="slider"
195 tabindex="0"
196 aria-valuemin="0"
197 aria-valuemax="100"
198 aria-valuenow="<?php echo esc_attr( $initial_position ); ?>"
199 aria-label="<?php esc_attr_e( 'Drag to compare images', 'frontblocks' ); ?>"
200 >
201 <span class="frbl-before-after__handle-line"></span>
202 <span class="frbl-before-after__handle-thumb">
203 <svg viewBox="0 0 20 20" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
204 <path d="M7 4l-4 6 4 6M13 4l4 6-4 6"/>
205 </svg>
206 </span>
207 <span class="frbl-before-after__handle-line"></span>
208 </div>
209 </div>
210 <?php
211 return ob_get_clean();
212 }
213 }
214