johannschopplich/kirby-blurry-placeholder

模糊图像占位符,提升用户体验

3.0.3 2023-07-19 08:42 UTC

This package is auto-updated.

Last update: 2024-09-19 08:44:16 UTC


README

注意

此插件已不再积极维护。我建议您结合使用 Kirby ThumbHashunlazy(一个进化的Loadeer.js)来获得类似的效果。它是此插件的继任者,并提供了一种更现代、更灵活的懒加载图像的方法。

感谢您多年来对我的支持和建议,尤其是它是我为Kirby编写的第一款插件以来!

ThumHash 和 unlazy 示例

内联图像缩略图

<img
  src="<?= $image->thumbhashUri() ?>"
  loading="lazy"
  data-srcset="<?= $image->srcset() ?>"
  data-sizes="auto"
  width="<?= $image->width() ?>"
  height="<?= $image->height() ?>"
>

使用 loading="lazy" 属性懒加载所有图像

import { lazyLoad } from 'unlazy'

// Apply lazy loading for all images by the selector `img[loading="lazy"]`
lazyLoad()

Preview of Kirby blurry placeholder plugin

Kirby Blurry Placeholder

此插件实现了渐进式图像加载,提供了更好的用户体验。继承自源图像宽高比的微小缩略图与模糊效果相结合,比纯色占位符更好,同时不牺牲负载。

工作原理

  1. 一个内联的、URI编码的SVG填充了给定图像元素的src属性。模糊图像被包裹在SVG中,以避免对滤镜进行光栅化。
  2. 大图像仅在它们位于视口内时才被请求。

主要功能

要求

  • Kirby 3 或
  • Kirby 4

安装

下载

下载并将此仓库复制到 /site/plugins/kirby-blurry-placeholder

Git 子模块

git submodule add https://github.com/johannschopplich/kirby-blurry-placeholder.git site/plugins/kirby-blurry-placeholder

Composer

composer require johannschopplich/kirby-blurry-placeholder

用法

作为Kirby图像块

每个Kirby网站都是根据其独特的用例定制的。因此,此插件默认不会添加Kirby块。相反,请查看提供的 图像块示例,以了解如何在块中实现模糊占位符。

当然,您可以直接将块复制到您的当前Kirby项目的 site/snippets/blocks 文件夹中,直接使用它,或根据您的需求对其进行修改!

作为文件方法

$file->placeholderUri() 创建并返回URI编码的SVG占位符。

<!-- Using the `placeholderUri` file method for the `src` attribute -->
<img
  src="<?= $image->placeholderUri() ?>"
  data-src="<?= $image->url() ?>"
  data-lazyload
  alt="<?= $image->alt() ?>"
/>

作为KirbyTag

此插件提供了一个基于Kirby核心 (image: …) 标签的 (blurryimage: …) KirbyTag。所有Kirby图像标签选项都被推断出来,因此也适用于自定义标签。

(blurryimage: …) 标签

  • 将模糊图像占位符编码为URI,并在src属性中。
  • 将原始图像的URL设置为data-src或一组响应式图像作为data-srcset
  • 添加data-lazyload属性,以便由懒加载库进行选择。

KirbyText字段中的示例使用

(blurryimage: myimage.jpg)
(blurryimage: myimage.jpg link: https://example.com)
(blurryimage: myimage.jpg class: is-poster)

如果您已启用选项中的srcset,则KirbyTag语法保持不变。只是输出有所变化。

前端懒加载

为了在图像在视口中可见时延迟加载图像,需要使用一个JavaScript库。🦌 Loadeer.js 是针对这个Kirby插件编写的,考虑到这一点。简单来说,它是一个小巧、高性能、SEO友好的延迟加载库,如果没有前端资产构建链,可以与或无需构建步骤使用。

无构建步骤 & 自动初始化

只需从CDN加载

<script
  src="https://unpkg.com/loadeer@2.1.1/dist/loadeer.umd.js"
  defer
  init
></script>
  • 代码 defer 属性使脚本在HTML内容解析后执行。
  • 代码 init 属性告诉Loadeer.js自动初始化并监视所有具有 data-lazyload 属性的元素。

作为ES模块导入

您可以通过安装 loadeer npm包使用ES模块构建

import Loadeer from "loadeer";

const instance = new Loadeer();
instance.observe();

自动计算 sizes 属性

Loadeer.js 支持自动设置 sizes 属性,对应于当前图像的大小。为了使此功能正常工作,必须将 data-sizes 属性设置为 auto。如果您在配置中启用了 srcset,则使用 (blurryimage: …) KirbyTag 时,这已经为您完成。

使用您选择的延迟加载器

每个解析的KirbyTag都将 data-lazyload 属性添加到 img 元素中。因此,您可以通过传递 [data-lazyload] 作为选择器,让选择的延迟加载器选择这些元素。

模糊动画

🎨 使用“模糊下降”技术进行动画处理

⚠️ 免责声明:请在本节阅读代码之前避免复制任何代码。这是一个带有警告(主要是性能问题)的实验性技术。

使用Loadeer.js时,我们可以针对所有具有 [data-lazyload] 的延迟加载图像,并仅通过 [data-src] 精细化此选择,以针对尚未完全加载的图像。

img[data-lazyload][data-src] {
  filter: blur(150px);
  transform: scale(1.2);
}

然后我们可以将过渡应用到这些属性上。

/* Respect users choice for reduced motion */
@media (prefers-reduced-motion: no-preference) {
  img[data-lazyload] {
    transition: 1000ms cubic-bezier(0.86, 0.07, 0.07, 0.96);
    transition-property: filter, transform;
    /* Hint browser at change for better performance */
    will-change: filter, transform;
  }
}

由于我们手动模糊了 img 元素(其 src 属性是我们的生成的SVG,因此本质上SVG是 img 元素的子元素),我们需要一个容器来隐藏溢出的部分。为了提高性能,我们还通过应用 transform 声明来强制GPU渲染。

.img-container {
  overflow: hidden;
  /* Enforce GPU rendering */
  transform: translateZ(0);
}

此实现的最大的弊端是 filter 的过渡 - 拥有低端设备的用户可能会遇到帧率下降。即使使用 transform 来强制GPU渲染并使用 will-change 作为最后的手段来提示过渡,也并不总是能解决这个问题。最后,这主要取决于您的最终用户使用的设备,网站上绘制的图像有多大,以及您的网站上有多少图像(所有这些图像可能同时模糊)。

那么您应该实现“模糊下降”过渡吗?可能不是。 如果您这样做,强烈考虑这些弊端。最好的动画是能吸引用户的动画,而不是吓到用户的动画。

选项

文件方法

两个文件方法 $file->placeholder()$file->placeholderUri() 都支持以下作为关联数组传递的选项

示例

$file->placeholderUri([
  'ratio' => 1.5,
  'transparent' => true
]);

透明图像

如果您知道您的图像(例如,一个徽标)是透明的,您可以将 transparent 选项传递给 placeholderUri()绕过生成的模糊边缘的伪影

<img src="<?= $image->placeholderUri(['transparent' => true]) ?>" />

如果没有明确指定,透明度将通过评估缩略图中每个像素的alpha通道(通过给定的像素目标)来检测。如果图像本身不包含alpha通道,则将在SVG占位符中添加额外的过滤器,以删除生成的模糊边缘的alpha通道。

有比例的图像

ratio选项传递给原始图像上的placeholderUri()方法,以生成具有特定比例的占位图

<?php $cropped = $original->crop(500, 400) ?>
<img
  src="<?= $original->placeholderUri(['ratio' => 5/4]) ?>"
  data-src="<?= $cropped->url() ?>"
  data-lazyload
  alt="<?= $original->alt() ?>"
/>

ℹ️ Kirby不支持裁剪图像的文件方法,因为后者继承了Kirby\Cms\FileVersion类。

全局

所有srcset选项都必须包裹在数组中。

选项可以在你的config.php文件中设置

return [
    'johannschopplich.blurry-placeholder' => [
        'pixel-target' => 60,
        'kirbytag' => [
            'srcset-preset' => 'article'
        ]
    ]
];

占位图应用实例

注意:GIF被减速,以便在图像加载之前直观地查看占位图的外观。

GIF showing plugin in action

致谢

许可证

MIT许可证 © 2020-2023 Johann Schopplich