area17/twill-image

v2.0.0 2024-07-25 12:15 UTC

README

Twill Image 是一个用于与 Twill 一起工作的包,可轻松在您的网站上显示响应式图片。它利用 Twill 的图像处理功能并添加了现代的懒加载技术。它支持响应式图像、艺术指导和固定宽度图像。

  • 带有多个 <source> 元素的 <picture>
  • Twill 的低质量占位符 (LQIP)
  • 艺术指导(多裁剪)
  • 支持 WebP 和 JPEG
  • 使用 loading='lazy' 的原生懒加载
  • 支持使用 Tailwind CSS 的自定义 CSS 类

内容

安装

使用 Composer 将包安装到现有的 Twill 项目中。

composer require area17/twill-image

配置文件

配置文件包含一些通用设置,您可以在其中定义图像预设。

config/twill-image.php 发布到应用程序的配置文件夹。

php artisan vendor:publish --provider="A17\Twill\Image\TwillImageServiceProvider" --tag=config

使用

Image 模型

Image 模型允许您与媒体对象流畅交互。

$image = new A17\Twill\Image\Models\Image($object, $role, $media);

// or using the Facade
$image = TwillImage::make($object, $role, $media);

可用方法

创建 Image 模型的实例后,您可以通过使用一个或多个这些方法进行交互。

裁剪

您可以通过传递参数来指定裁剪名称。默认情况下,Image 模型将寻找名为 default 的裁剪名称,如果不可用,它将寻找单个裁剪并选择它。如果无法确定裁剪,将导致错误。

$image->crop('listing_card');
宽度

要设置图像的宽度,您可以使用此方法。默认宽度为 1000 像素。如果您需要显示具有固定宽度的图像或预先知道需要比默认图像更大的图像,这非常有用。

注意:宽度应用于“回退”图像(<img src="{{ $image }}">)并确定要添加到 srcset 属性中的图像 URL 数量。

$image->width(1500);
高度

您可以使用此方法设置图像的高度。与上面的 width 方法类似,它对于固定大小的图像最有用。如果没有使用,高度将根据图像的宽高比和宽度推断。

$image->height(900);

$image->crop('listing')->width(600)->height(400);
来源

要使用多个 <source> 元素,您可以传递一个数组到此方法,列出除主裁剪以外的来源。数组中的每个项目必须有一个 mediaQuery 和一个 crop 键,以便生成正确的 srcset。您可以传递可选的宽度和高度。这在与 crop 方法一起使用时很有用,以设置主图像裁剪。另请参阅艺术指导图像

$image->crop('desktop')->sources([
    [
        'mediaQuery' => '(max-width: 400px)', // required
        'crop' => 'mobile', // required
        'width' => 200, // optional
        'height' => 200, // optional
        'srcSetWidths' => [100, 200, 400], // optional
    ],
    [
        'mediaQuery' => '(min-width: 401px) and (max-width: 700px)',
        'crop' => 'tablet',
    ],
]);

媒体查询也可以通过传递一个具有 columns 键而不是 mediaQuery前端断点和网格结构 文件来生成。您可以在下面看到格式。

$image->crop('desktop')->sources([
    [
        'columns' => [
            'md' => 'max',
        ],
        'crop' => 'mobile',
    ],
    [
        'columns' => [
            'md' => 'min',
            'lg' => 'max',
        ],
        'crop' => 'tablet',
    ],
]);
大小

使用此方法向模型传递一个 sizes 属性。

$image->sizes('(max-width: 400px) 100vw, 50vw');

作为sizes方法的替代方案,Twill Image提供了一种根据前端断点和网格结构文件生成sizes属性的方法。当将此JSON文件放置在应用的基本文件夹中时,可以通过传递一系列断点和列数来生成sizes属性。

$image->columns([
    'xxl' => 6,
    'xl' => 6,
    'lg' => 8,
    'md' => 8,
    'sm' => 8,
    'xs' => 12,
]);

这将说明图像在每个断点将占用多少列,以生成适当的sizes属性。

注意:此方法仅在应用基本文件夹中存在frontend.config.json文件时才会生效。

srcSetWidths

使用此方法来提供一个宽度列表以生成srcset属性。如果没有此方法,Twill Image将根据图像宽度自动生成一系列宽度。

$image->srcSetWidths([100, 150, 300, 600, 1200, 2000, 2400, 3600, 5000]);
预设

使用此方法,您可以使用对象将值传递给上述任何方法。您还可以在配置文件config/twill-image.php中添加预设键并传递名称到该方法。

// config/twill-image.php

return [
    // ...
    'presets' => [
        'art_directed' => [
            'crop' => 'desktop',
            'width' => 700,
            'sizes' => '(max-width: 767px) 25vw, (min-width: 767px) and (max-width: 1023px) 50vw, 33vw',
            'srcSetWidths' => [350, 700, 1400],
            'sources' => [
                [
                    'crop' => 'mobile',
                    'media_query' => '(max-width: 767px)',
                    'srcSetWidths' => [100, 200, 400],
                ],
                [
                    'crop' => 'tablet',
                    'media_query' => '(min-width: 767px) and (max-width: 1023px)',
                ],
            ],
        ],
    ],
];
// to use this preset from the config file
$image->preset('art_directed');

如果您更喜欢,可以直接传递完整的对象。

$image->preset([
    'crop' => 'desktop',
    'width' => 700,
    'sizes' => '(max-width: 767px) 100vw, (min-width: 767px) and (max-width: 1023px) 50vw, 33vw',
    'sources' => [
        [
            'crop' => 'mobile',
            'media_query' => '(max-width: 767px)',
        ],
        [
            'crop' => 'tablet',
            'media_query' => '(min-width: 767px) and (max-width: 1023px)',
        ],
    ],
]);
渲染

此方法将返回渲染后的视图。

{{-- resources/views/home.blade.php --}}
@php
$image = TwillImage::make($page, 'preview')->preset('art_directed');
@endphp

{!! $image->render() !!}

{{-- with arguments --}}
{!! $image->render([
    'loading' => 'eager',
]) !!}
toArray

如果您需要将图像生成与渲染分开(例如,通过REST API公开Image模型数据),请使用此方法获取所有属性作为数组。

$previewImage = TwillImage::make($page, 'preview')->preset('art_directed')->toArray();

然后使用外观的render方法来渲染视图。

{{-- resources/views/page.blade.php --}}

<div>{!! TwillImage::render($previewImage) !!}</div>

外观 render 方法

如前所述,图像元素渲染可以与图像属性生成分开。您可以使用Image模型设置您的图像,并将结果对象(或其array格式)传递给render方法以输出视图。

$previewImage = TwillImage::make($page, 'preview')->toArray();
{!! TwillImage::render($previewImage) !!}

<div class="w-1/4">
    {!! TwillImage::render($previewImage, [
        'width' => 700,
    ]) !!}
</div>

参数列表

示例

{!! TwillImage::make($item, 'preview_image')->sizes('(max-width: 767px) 50vw, 100vw')->render(); !!}

@php
$heroImage = TwillImage::make($item, 'preview_image');
$listingImage = TwillImage::make($item, 'preview_image')->crop('listing');
@endphp

{!! TwillImage::render($heroImage) !!}

{!! TwillImage::render($listingImage) !!}

配置

config/twill-image.php中,您可以定义通用选项和图像预设。预设通知Image::preset方法要输出的裁剪以及其他选项,如响应式源。

<?php

return [

    // ...

    'presets' => [
        'listing' => [
            'crop' => 'card',
            'width' => 500,
            'sizes' => '25vw',
        ],
        // ...
    ],
];

预设

有关preset方法的说明,请参阅上文

选项列表

艺术指导图像

要使用媒体查询的不同裁剪,您需要在Image::preset或通过将它们传递给Image::sources方法中列出其他源。渲染的图像元素将仅具有主裁剪的比率,其他比率需要通过CSS添加。

假设这是您在配置中的预设art_directed

    // ...
    'art_directed' => [
        'crop' => 'desktop',
        'sizes' => '(max-width: 767px) 100vw, 50vw',
        'sources' => [
            [
                'crop' => 'mobile',
                'media_query' => '(max-width: 767px)',
            ]
        ],
    ],
    // ...
@php
$image = TwillImage::make($page, 'preview')->preset('art_directed');
@endphp

<div>
    {!! TwillImage::render($image, [
        'class' => 'art-directed'
    ]) !!}
</div>

它将输出应用了类到容器的图像元素。

<div class="twill-image-wrapper art-directed">...</div>

为每个断点定义样式。

.art-directed {
  aspect-ratio: 16 / 9;
}

@media screen and (max-width: 767px) {
  .art-directed {
    aspect-ratio: unset;
  }
}

前端断点和网格结构

我们提供了一种通过在应用基本文件夹中放置JSON文件frontend.config.json来描述页面结构的方法,以生成sizesmedia属性。一个示例是frontend.config.json.example

该文件描述了断点、主容器宽度、每个断点的列数以及内边距和外边距。当此文件存在于您的项目中时,您可以使用Image模型上的columns方法或预设和源对象中的columns键来动态生成sizesmedia属性。

columns 示例

此示例假设您在应用的基本路径base_path中提供了提供的frontend.config.json

columns 预设

// config/twill-image.php

return [
    // ...
    'presets' => [
        'art_directed' => [
            'crop' => 'desktop',
            'columns' => [
                'xxl' => 6,
                'xl' => 6,
                'lg' => 8,
                'md' => 8,
                'sm' => 8,
                'xs' => 12,
            ],
            'sources' => [
                [
                    'crop' => 'mobile',
                    'columns' => [
                        'md' => 'max',
                    ],
                ],
                [
                    'crop' => 'tablet',
                    'columns' => [
                        'md' => 'min',
                        'lg' => 'max',
                    ],
                ],
            ],
        ],
    ],
];

columns 输出

{{-- to use this preset from the config file and render the image --}}
{!! $image->preset('art_directed')->render() !!}

图像源和后备将具有这些sizesmedia属性(元素已简化以清晰)

<picture>
    <source media="(max-width: 767px)" sizes="..." srcset="...">
    <source media="(min-width: 768px) and (max-width: 1023px)" sizes="..." srcset="...">
    <img sizes="
        (max-width: 543px) calc((((100vw - 260px) / 12) * 12) + 220px),
        (min-width: 544px) and (max-width: 767px) calc((((100vw - 312px) / 12) * 8) + 168px),
        (min-width: 768px) and (max-width: 1023px) calc((((100vw - 416px) / 12) * 8) + 224px),
        (min-width: 1024px) and (max-width: 1279px) calc((((100vw - 624px) / 12) * 8) + 336px),
        (min-width: 1280px) and (max-width: 1680px) calc((((100vw - 832px) / 12) * 6) + 320px),
        761px
    " src="...">
</picture>

columns 自定义类

您可以使用自己的自定义类来替换提供的类。您可以在配置文件中创建自己的服务并指定类名。

// config/twill-image.php

    // ...
    // default to: A17\Twill\Image\Services\ImageColumns::class
   'columns_class' => MyApp\Services\MyOwnImageColumnsService::class,

];

该服务必须实现接口A17\Twill\Image\Services\Interfaces\ImageColumns

如果只需要覆盖提供的服务中定义的一些属性,这也很有用。

多媒体

这是一个示例,当您在单个role中附加多个媒体时:

@php
$galleryImages = $item->imageObjects('gallery_image', 'desktop')->map(function ($media) use ($item) {
    return TwillImage::make($item, 'gallery_image', $media);
})->toArray();
@endphp

@if($galleryImages)
    @foreach($galleryImages as $image)
        {!! TwillImage::render($image) !!}
    @endforeach
@endif