You are here

public static function BlazyBreakpoint::buildDataBlazy in Blazy 7

Builds breakpoints suitable for top-level [data-blazy] wrapper attributes.

The hustle is because we need to define dimensions once, if applicable, and let all images inherit. Each breakpoint image may be cropped, or scaled without a crop. To set dimensions once requires all breakpoint images uniformly cropped. But that is not always the case.

Parameters

array $settings: The settings being modified.

object $item: The image item.

Overrides BlazyBreakpointInterface::buildDataBlazy

File

src/BlazyBreakpoint.php, line 126

Class

BlazyBreakpoint
Implements BlazyBreakpointInterface.

Namespace

Drupal\blazy

Code

public static function buildDataBlazy(array &$settings, $item = NULL) {

  // Identify that Blazy can be activated by breakpoints, regardless results.
  $settings['blazy'] = TRUE;

  // Bail out if already defined at BlazyFormatter::setImageDimensions().
  // Blazy doesn't always deal with image formatters, see self::isBlazy().
  if (!empty($settings['blazy_data'])) {
    return;
  }

  // May be set at BlazyFormatter::setImageDimensions() if using formatters,
  // yet not set from non-formatters like views fields, see self::isBlazy().
  Blazy::imageDimensions($settings, $item, TRUE);
  $json = $sources = $styles = [];
  $end = end($settings['breakpoints']);

  // Check for cropped images at the 5 given styles before any hard work
  // Ok as run once at the top container regardless of thousand of images.
  foreach ($settings['breakpoints'] as $key => $breakpoint) {
    if (blazy()
      ->isCrop($breakpoint['image_style'])) {
      $styles[$key] = TRUE;
    }
  }

  // Bail out if not all images are cropped at all breakpoints.
  // The site builder just don't read the performance tips section.
  if (count($styles) != count($settings['breakpoints'])) {
    return;
  }

  // We have all images cropped here.
  foreach ($settings['breakpoints'] as $key => $breakpoint) {
    if ($width = self::widthFromDescriptors($breakpoint['width'])) {

      // If contains crop, sets dimension once, and let all images inherit.
      if (!empty($settings['ratio'])) {
        $dimensions = Blazy::transformDimensions($breakpoint['image_style'], $item);
        $padding = round($dimensions['height'] / $dimensions['width'] * 100, 2);
        $json['dimensions'][$width] = $padding;

        // Only set padding-bottom for the last breakpoint to avoid FOUC.
        if ($end['width'] == $breakpoint['width']) {
          $settings['padding_bottom'] = $padding;
        }
      }

      // If BG, provide [data-src-BREAKPOINT], regardless uri or ratio.
      if (!empty($settings['background'])) {
        $sources[] = [
          'width' => (int) $width,
          'src' => 'data-src-' . $key,
        ];
      }
    }
  }

  // As of Blazy v1.6.0 applied to BG only.
  if ($sources) {
    $json['breakpoints'] = $sources;
  }

  // Supported modules can add blazy_data as [data-blazy] to the container.
  // This also informs individual images to not work with dimensions any more
  // as _all_ breakpoint image styles contain 'crop'.
  if ($json) {
    $settings['blazy_data'] = $json;
  }
}