在PHP中生成响应式背景图像大小

时间:2017-06-11 作者:Dovid Levine

我正在尝试为我的页眉生成响应性的背景图像,使用此的修改版本gist, 但是我不能让它正常工作,我也不确定问题是否出在wp_get_attachment_image_srcset, wp_calculate_image_sizes 或者循环本身。

这是我的代码:

Responsive Image Size Attributes

function adjust_image_sizes_attr( $sizes, $size ) {
    $width = $size[0];
    if($width >= 1260){
        $sizes = \'(max-width:575px) 575px, (max-width:767px) 767px, (max-width:991px) 991px, (max-width:1199px) 1199px, 1260px)\';
    }
    elseif($width >= 900){
        $sizes = \'(max-width:767px) 100vw, (max-width:991px) 631px, (max-   width:1199px) 839px, 900px)\';
    }
    elseif($width >= 600){
        $sizes = \'(max-width:767px) 100vw, 600px\';
    }
    else{
        $sizes= \'(max-width: \' . $width . \'px) 100vw, \' . $width . \'px\';
    }

    return $sizes;
}
add_filter( \'wp_calculate_image_sizes\', __NAMESPACE__ . \'\\\\adjust_image_sizes_attr\', 10 , 2 );

Generate Responsive Background Image CSS

function gsc_responsive_bg_images($attachment_id, $img_size, $selector)
{
    $img_srcset = wp_get_attachment_image_srcset( $attachment_id, $img_size );
    $sizes = explode( ", ", $img_srcset );
    $css = \'\';
    $prev_size = \'\';
    foreach( $sizes as $size ) {

        // Split up the size string, into an array with [0]=>img_url, [1]=>size
        $split = explode( " ", $size );
        if( !isset( $split[0], $split[1] ) )
            continue;

        $background_css = \'.gsc-page-title-bar {
            background-image: url(\' . esc_url( $split[0] ) . \')
        }\';

        // Grab the previous image size as the min-width and/or add the background css to the main css string
        if( !empty( $prev_size ) ) {
            $css .= \'@media only screen and (min-width: \' . $prev_size . \') {\';
            $css .= $background_css;
            $css .= "}\\n";
        } else {
            $css .= $background_css;
        }

        // Set the current image size as the "previous image" size, for use with media queries
        $prev_size = str_replace( "w", "px", $split[1] );
    }
    return $css;
} 
**我的输出:(简写)**默认值。jpg(原始尺寸:1170w)

@min-width: 1170px -> 768w.jpg
@min-width: 768px -> 120w.jpg
@min-width: 120px -> 500w.jpg
@min-width: 500px -> 700w.jpg
@min-width: 700px -> 200w.jpg
@min-width: 400px -> 600w.jpg
@min-width: 600px -> 800w.jpg
我在期待

看到这一点,我留下了一大堆问题:

为什么这是返回的CSS代码?它不应该是在默认断点处返回的最小大小和在@min-width:1170px? 为什么@min-width: 768px -> 120w.jpg , 和@min-width: 700px -> 200w.jpg?

1 个回复
SO网友:Terrapin

我还没有测试过你的代码,但最近我花了几个小时一起破解了一些东西来解决同样的问题——通过WordPress定制器相应地加载背景图像。请根据您的需要随意使用/修改下面的代码,并以我的方式发送任何问题。无论如何,我都不是PHP专家。

关于下面的代码,需要注意三件事:

  1. 我假设您已经设置了自定义程序代码,或者可以通过回音/过滤器将此CSS添加到其他地方function 根据Michah Wood创建的URL获取附件的ID,Michah Wood将此归功于此function 由Andrey Savchenko(又名“Rarst”)开发。我已经在下面的第二个函数中包含了它,但请确保查看这两个链接以获取更多信息

响应式定制器背景

    /**
     * Create CSS Rules for Responsive BGs set via the Wordpress Customizer.
     *
     * @uses get_attachment_id()            Gets attachment id from $img_url
     * @link https://wpscholar.com/blog/get-attachment-id-from-wp-image-url/
     *
     * @param string $selector              The css selector set via customizer
     * @param string $img_url               The attachment url set via customizer
     *
     * @return string $responsive_css       CSS rules on success, 0 on failure
     */

    function responsive_customizer_bgs($selector=\'\', $img_url=\'\') {

      // return var
      $responsive_css = 0;

      // get attachment id based on url (uses helper func)
      $image_id = get_attachment_id( $img_url );

      // get the src string from WP
      $srcset_string = wp_get_attachment_image_srcset( $image_id, \'full\' );

      // parse srcset string into [url][int][width-or-pixel-density]
      preg_match_all(
        "/([^\\s]*)\\s(\\d*)([w|x])/",
        $srcset_string,
        $srcset_matches,
        PREG_SET_ORDER
      );

      // check if regex match was successful
      if( is_array($srcset_matches) ) {

          // cast int string into integer
          for ($i=0; $i < count($srcset_matches); $i++) {
              $srcset_matches[$i][2] = (int) $srcset_matches[$i][2];
          }

          // sort array of sizes by integer
          usort($srcset_matches, function($a, $b) {
            return $a[2] >= $b[2] ? -1 : 1;
          });

          // indexed loop to walk multi-dimensional array returned by regex
          for ($i=0; $i < count($srcset_matches); $i++) {
              // set media query statement based pixel size or pixel density
              if ($srcset_matches[$i][3] === \'w\') {
                  $media_query_match = \'max-width: \' . $srcset_matches[$i][2] . \'px\';
              } else if ($srcset_matches[$i][3] === \'x\') {
                  $media_query_match = \'-webkit-min-device-pixel-ratio: \' . $srcset_matches[$i][2];
              }

              // create css rules and add to return string
              $responsive_css .= PHP_EOL
                . \'@media only screen and (\' . $media_query_match . \') {\' . PHP_EOL
                . \'  \' . $selector . \' {\' . PHP_EOL
                . \'    background-image: url(\' . $srcset_matches[$i][1] . \');\' . PHP_EOL
                . \'  }\' . PHP_EOL
                . \'}\';

          }

          // return that beautiful responsiveness
          return $responsive_css;

      }

    }
通过URL获取附件ID
    /**
     * Get an attachment ID given a URL.
     * 
     * @param string $url
     *
     * @return int Attachment ID on success, 0 on failure
     */
    function get_attachment_id( $url ) {
        $attachment_id = 0;
        $dir = wp_upload_dir();
        if ( false !== strpos( $url, $dir[\'baseurl\'] . \'/\' ) ) { // Is URL in uploads directory?
            $file = basename( $url );
            $query_args = array(
                \'post_type\'   => \'attachment\',
                \'post_status\' => \'inherit\',
                \'fields\'      => \'ids\',
                \'meta_query\'  => array(
                    array(
                        \'value\'   => $file,
                        \'compare\' => \'LIKE\',
                        \'key\'     => \'_wp_attachment_metadata\',
                    ),
                )
            );
            $query = new WP_Query( $query_args );
            if ( $query->have_posts() ) {
                foreach ( $query->posts as $post_id ) {
                    $meta = wp_get_attachment_metadata( $post_id );
                    $original_file       = basename( $meta[\'file\'] );
                    $cropped_image_files = wp_list_pluck( $meta[\'sizes\'], \'file\' );
                    if ( $original_file === $file || in_array( $file, $cropped_image_files ) ) {
                        $attachment_id = $post_id;
                        break;
                    }
                }
            }
        }
        return $attachment_id;
    }

结束

相关推荐

Menu Responsive

如何使菜单栏响应?当我将窗口裁剪为手机大小时,菜单不会随标题一起更改,在标题图像和菜单栏之间留下空白,或者重复显示两次菜单。