使用高斯模糊效果一步步加载图片(类似Medium)
时间:2023-03-15 22:54:12
科技观察
用过Medium的用户一定不会忘记它的图片加载方式——纯色——高斯模糊——加载完成并显示。这是一种非常优雅的图片预加载方式(因为Medium的图片质量很高,一次加载它们会花费难以想象的时间,所以这是一个很好的方法)。从我第一次打开Medium站点开始,我就对这项技术着迷了——好吧,直到今天我才深入研究它。在Medium网站上,打开任何文章,然后让我们检查它:锁定">
可以看到Medium就是每张图片设置这么长一段HTML,这样做的目的是为了让图片的渐进加载过程流畅一致,同时一定程度上提升用户体验,即使图片没有加载,展示给用户的是一张高斯模糊的图片,其实很美。那么,这张图片的渐进加载过程是怎样的呢?渲染一个div容器,用来展示最终展示给用户的图片。通过容器设置padding-botto的百分比m使其比例和大小与最终图片一致,避免图片加载时页面重排;使用img标签加载一张原图质量大约10%~20%的图片,这张图片质量很低而且很小,可以马上加载;小图加载完成后,开始使用canvas绘制,添加模糊效果,并开始请求加载最终的大图;当加载最终的大图像时,显示大图像并隐藏画布。以上是Medium的做法。我们可以自己实现这个效果,实现过程如下:渲染一个容器,保持与原图相同的比例和大小,并填充较浅的背景色;先加载小图,同时使用模糊效果;小图加载完毕,开始请求大图;加载大图,显示大图,隐藏小图。所以,总的来说,其实并不复杂。首先我们可以保存大小图的url和大小,通过标签的data属性动态获取。所以,我们的HTML可以这样写:sm2.jpeg"src="https://cdn-images-1.medium.com/max/2000/1*0WwtDkE1q6HGZwD6Kn9SuQ.jpeg">各参数含义为:data-real-width:大图的宽度data-real-height:大图的高度data-src:小图的URLsrc:大图的URL同时我们需要定义一些CSS类来处理大图和小图:.blur-img-container{position:relative;background:#eeeeee;background-size:cover;overflow:hidden;}.blur-img-containerimg{position:absolute;top:0;left:0;宽度:100%;高度:100%;不透明度:0;过渡:all0.4sease-in-out;}.blur-img-container.thumb-loaded{opacity:1;filter:blur(10px);变换:比例(1);}。blur-img-container.large-loaded{opacity:1;}.blur-img-container.thumb-hidden{opacity:0;}然后,我们的重点是JavaScript处理。需要动态设置每张图片容器的padding-bottom,防止页面重排;通过图片的onload事件来控制它的样式和进度点,动态设置我们容器的padding-bottom。你可以计算宽高比,然后将其转换成百分比:elem.style.paddingBottom=`${(realHeight/realWidth)*100}%`;二、使用图片的onload事件控制加载进度:letthumb=newImage();thumb.src=thumbSrc;thumb.onload=()=>{//缩略图加载完毕,显示缩略图,设置样式setStyle(thumb,'thumb-loaded');};elem.appendChild(thumb);letrealImg=newImage();realImg.src=lgSrc;realImg.onload=()=>{//加载大图,显示大图,隐藏小图setStyle(realImg,'large-loaded');setStyle(thumb,'thumb-hidden');};//给页面添加大图elem.appendChild(realImg);其实只要做好以上两个主要功能,我们的效果就基本实现了。完整的源代码和示例模糊图像可以通过我的GitHubRepo查看。同时我把这个小功能封装成一个包,需要的朋友可以通过npminstallblur-image或者bowerinstallblur-image安装使用。具体安装和使用方法请参考文档。