资讯专栏INFORMATION COLUMN

使用高斯模糊的效果逐步加载图片(仿 Medium)

LeexMuller / 289人阅读

摘要:我们可以自己来实现这个效果,实现过程如下渲染一个容器,保持与原图的比例和尺寸相同,填充一个较浅的背景色先加载小图,同时使用模糊效果小图加载完成,开始请求大图大图加载完成,显示大图,隐藏小图。

用过 Medium 的用户不会不记得它的图片加载方式——纯色-高斯模糊-加载完成并显示

这是一种很优雅的图片预加载的方式(因为 Medium 的图片质量都很高,如果全部一下加载的话,需要的时间难以想象,所以,这是一种很棒的做法)。从第一次打开 Medium 这个网站开始,我就被这种技术给吸引住了——好吧,直到今天才去研究它。

在 Medium 网站,打开任何一篇文章,然后,我们来 inspect 一下:

可以看到,Medium 为每一张图片都设置了这么长的一段 HTML。这样做的目的就是为了让这个图片的逐步加载过程能够平滑如一,同时还能在一定程度上提升用户体验。就算图片没有加载出来,显示给用户的是一个高斯模糊的图片,其实也不失美感。

那么,这个图片的逐步加载过程具体是什么样的呢?

渲染一个 div 容器,这个容器就是用来显示最终展示给用户的图片的。通过对容器设置一个百分比的 padding-bottom 来让其比例和大小与最终图片的比例和大小相同,这样,就能避免图片加载出来的时候导致的页面的重排;

使用 img 标签来加载一张原图质量的 10% ~ 20% 左右的图片,这张图片的质量很低,而且很小,所以可以马上加载出来;

一旦小图加载完成,就开始使用 canvas 来进行绘制,添加模糊效果,同时,开始请求最终要加载的大图;

当最终的大图也加载完成之后,显示大图,隐藏掉 canvas。

以上就是 Medium 的做法。

我们可以自己来实现这个效果,实现过程如下:

渲染一个容器,保持与原图的比例和尺寸相同,填充一个较浅的背景色;

先加载小图,同时使用模糊效果;

小图加载完成,开始请求大图;

大图加载完成,显示大图,隐藏小图。

所以,综合来看,其实并不复杂。

首先,我们可以把大图和小图的 URL 和尺寸都存起来,通过标签的 data 属性去动态获取。所以,我们的 HTML 可以像下面这样写:

其中各个参数代表的含义是:

data-real-width: 大图的宽度

data-real-height: 大图的高度

data-src: 小图的 URL

src: 大图的 URL

同时,我们需要定义一些 CSS 的 class 来对大图和小图进行处理:

.blur-img-container {
    position: relative;
    background: #eeeeee;
    background-size: cover;
    overflow: hidden;
}

.blur-img-container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: all 0.4s ease-in-out;
}

.blur-img-container .thumb-loaded {
    opacity: 1;
    filter: blur(10px);
    transform: scale(1);
}

.blur-img-container .large-loaded {
    opacity: 1;
}

.blur-img-container .thumb-hidden {
    opacity: 0;
}

然后,我们的重点在于 JavaScript 的处理。

需要动态的设置每个图片的容器的 padding-bottom 以防止页面发生重排;

通过 imageonload 事件来控制其样式和进度

第一点,动态设置我们的容器的 padding-bottom。可以通过计算宽高比然后换算成百分比:

elem.style.paddingBottom = `${(realHeight / realWidth) * 100}%`;

第二点,使用图像的 onload 事件来控制加载的进度:

let thumb = new Image();
thumb.src = thumbSrc;
thumb.onload = () => {
    // 小图加载完成,显示小图,设置样式
    setStyle(thumb, "thumb-loaded");
};
elem.appendChild(thumb);

let realImg = new Image();
realImg.src = lgSrc;
realImg.onload = () => {
    // 大图加载完成,显示大图,隐藏小图
    setStyle(realImg, "large-loaded");
    setStyle(thumb, "thumb-hidden");
};

// 将大图添加到页面中
elem.appendChild(realImg);

其实,只要把上面两点主要的功能做好了,我们的这个效果基本上就实现了。

可以通过我的 GitHub Repo 来查看完整的源代码和例子 blur-image

同时,我将这个小功能封装成了一个 package,需要的朋友可以通过 npm install blur-image 或者 bower install blur-image 进行安装和使用。具体的安装和使用方法可以查看文档

参考链接
How Medium does progressive image loading
The “Blur Up” Technique for Loading Background Images

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80218.html

相关文章

  • 使用高斯模糊效果逐步加载图片仿 Medium

    摘要:我们可以自己来实现这个效果,实现过程如下渲染一个容器,保持与原图的比例和尺寸相同,填充一个较浅的背景色先加载小图,同时使用模糊效果小图加载完成,开始请求大图大图加载完成,显示大图,隐藏小图。 用过 Medium 的用户不会不记得它的图片加载方式——纯色-高斯模糊-加载完成并显示。 这是一种很优雅的图片预加载的方式(因为 Medium 的图片质量都很高,如果全部一下加载的话,需要的时间难...

    tinyq 评论0 收藏0
  • 图片处理工具 - 收藏集 - 掘金

    摘要:图片预览工具掘金仿微信的图片预览工具这是一个仿朋友圈的列表。加载图片工具使处理发送大图掘金什么是就是内存溢出,即。图片加载框架最详细的使用指南掘金写在前面中有几个比较有名的图片加载框架,和。 Android 图片预览工具 - Android - 掘金仿微信的图片预览工具 01.png 这是一个仿朋友圈的列表。 加载图片工具使... 处理 Android 发送大图 OOM - Andro...

    AbnerMing 评论0 收藏0
  • Android酷炫动画效果

    摘要:高级特效之酷炫抢红包金币下落动画最近项目需求要求做一个抢红包特效。使用动画让页面跳转更炫酷中引入了很多炫酷的动画效果,便是其中一种。 Android自定义View:一个精致的打钩小动画 一个精致的打钩动画。 Android 自定义水平进度条圆角进度 项目中实现进度条进度过程中显示圆角样式 ViewPager系列之 仿魅族应用的广告BannerView 前言 Banner广告位是APP ...

    scq000 评论0 收藏0
  • 图片处理工具

    摘要:但是我们还是发现至少有两个问题,以为例,第一,当需求变动,你最全面详解图像处理的最重要类之一。将图片存储到一个特殊的区域,避免了。 Android7.0 完美适配——FileProvider 拍照裁剪全解析 适配 android7.0 中的拍照相册裁剪功能 使用 photoView 实现可点击放大到全屏显示的控件,效果类似于微信朋友圈点开看大图 使用 photoView 实现可点击放大...

    wangxinarhat 评论0 收藏0
  • Android view - 收藏集 - 掘金

    摘要:掘金一个可实现长按扫描上的二维码的工具库。说到刷新加载,我们第一个想到啥,对了从头开始学四类添加和多种的支持掘金来张图前言敲酷炫的切换效果和弹性指示器。掘金效果图使用方法依赖注意使用时需要在父布局中加入仿讨论组头像掘金仿讨论组头像基 仿美团详情滑动界面,并兼容 NestedScroll 嵌套 - Android - 掘金不论什么APP应该都会有个app产品的详情界面, 详情界面往往也比...

    IntMain 评论0 收藏0

发表评论

0条评论

LeexMuller

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<