运用高斯隐约的结果逐渐加载图片(仿 Medium)

用过 Medium 的用户不会不记得它的图片加载体式格局——纯色-高斯隐约-加载完成并显现

这是一种很文雅的图片预加载的体式格局(由于 Medium 的图片质量都很高,假如悉数一下加载的话,须要的时刻不可思议,所以,这是一种很棒的做法)。从第一次翻开 Medium 这个网站最先,我就被这类手艺给吸收住了——好吧,直到今天赋去研讨它。

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

<figure name="512a" 
        id="512a" 
        class="graf--figure graf--layoutCroppedHeightPreview graf-after--h3"
>
    <div class="aspectRatioPlaceholder is-locked">
        <div class="aspectRatioPlaceholder-fill" 
             style="padding-bottom: 30%;"
        ></div>
        <div class="progressiveMedia js-progressiveMedia graf-image is-canvasLoaded" 
             data-image-id="1*dZnfeZiXxf2BgN3VSQuOlA.jpeg" 
             data-width="3600" 
             data-height="3600" 
             data-scroll="native"
        >
            <img src="https://cdn-images-1.medium.com/freeze/fit/t/60/18/1*dZnfeZiXxf2BgN3VSQuOlA.jpeg?q=20" 
                 crossorigin="anonymous" 
                 class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail"
            >
            <canvas class="progressiveMedia-canvas js-progressiveMedia-canvas" 
                    width="75" 
                    height="22"
            ></canvas>
            <img class="progressiveMedia-image js-progressiveMedia-image" 
                 data-src="https://cdn-images-1.medium.com/fit/t/1600/480/1*dZnfeZiXxf2BgN3VSQuOlA.jpeg" 
                 src="https://cdn-images-1.medium.com/fit/t/1600/480/1*dZnfeZiXxf2BgN3VSQuOlA.jpeg"
            >
            <noscript class="js-progressiveMedia-inner">
                &lt;img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/fit/t/1600/480/1*dZnfeZiXxf2BgN3VSQuOlA.jpeg"&gt;
            </noscript>
        </div>
    </div>
</figure>

可以看到,Medium 为每一张图片都设置了这么长的一段 HTML。如许做的目标就是为了让这个图片的逐渐加载历程可以腻滑如一,同时还能在肯定程度上提拔用户体验。就算图片没有加载出来,显现给用户的是一个高斯隐约的图片,实在也不失美感。

那末,这个图片的逐渐加载历程详细是什么样的呢?

  1. 衬着一个 div 容器,这个容器就是用来显现终究展现给用户的图片的。经由过程对容器设置一个百分比的 padding-bottom 来让其比例和大小与终究图片的比例和大小雷同,如许,就可以防备图片加载出来的时刻致使的页面的重排;

  2. 运用 img 标签来加载一张原图质量的 10% ~ 20% 摆布的图片,这张图片的质量很低,而且很小,所以可以立时加载出来;

  3. 一旦小图加载完成,就最先运用 canvas 来举行绘制,增加隐约结果,同时,最先要求终究要加载的大图;

  4. 当终究的大图也加载完成以后,显现大图,隐蔽掉 canvas。

以上就是 Medium 的做法。

我们可以本身来完成这个结果,完成历程以下:

  1. 衬着一个容器,坚持与原图的比例和尺寸雷同,添补一个较浅的背景色;

  2. 先加载小图,同时运用隐约结果;

  3. 小图加载完成,最先要求大图;

  4. 大图加载完成,显现大图,隐蔽小图。

所以,综合来看,实在并不庞杂。

起首,我们可以把大图和小图的 URL 和尺寸都存起来,经由过程标签的 data 属性去动态猎取。所以,我们的 HTML 可以像下面如许写:

<figure name="blur"
        class="blur-img-container"
        data-real-width="1174"
        data-real-height="670"
        data-src="images/sm2.jpeg"
        src="https://cdn-images-1.medium.com/max/2000/1*0WwtDkE1q6HGZwD6Kn9SuQ.jpeg"
></figure>

个中各个参数代表的寄义是:

  • 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

    原文作者:Erichain_Zain
    原文地址: https://segmentfault.com/a/1190000006743512
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞