最近在作的小程序项目设计大量图片的展现,小程序已经提供了图片的懒加载功能,可是因为图片自己比较大加上要展现的图片比较多,如何以一个比较友好的方式展现未加载完成的过程就是一个必须解决的问题了。css
因为小程序没有提供 Image
这个 js
对象,因此在小程序中实现预加载不能直接像原生js
同样,直接使用 new Image()
建立一个图片对象,只能在视图层建立图片,经过onLoad
事件监听图片加载完成。ios
实现图片模糊加载的思路就是先加载一个目标图片的缩略图,缩略图的加载通常很是快能够忽略不计,缩略图加载完成以后以高斯模糊的形式展现,与此同时加载原图,原图加载完成后替代原缩略图,原图和缩略图须要设置相同的宽高。 思路理清楚以后,开始码代码吧~nginx
因为项目使用了
Taro
框架,下面的代码写法是React
的写法,原生或者其余框架也能够参考,没有太大的出入,思路都是同样的。小程序
imgLoader.js(如下为部分代码)bash
// 监听原图加载完成 toggleOriginLoaded() { this.setState({ loaded: true }); } // 监听缩略图加载完成 toggleThumbLoaded() { this.setState({ thumbLoaded: true }); } render() { let { loaded, thumbLoaded } = this.state; let { imgU, imgW, imgH } = this.props; // 根据传入的宽高设置缩略图和原图的宽高 let style = { width: imgW + 'rpx', height: imgH + 'rpx' } return ( <Block> <Image className='image--not-loaded' style={Object.assign({ display: loaded ? 'none' : 'auto' }, style)} lazyLoad mode='aspectFill' onLoad={this.toggleThumbLoaded.bind(this)} src={compressImage(imgU, '10x' + parseInt(imgH * 10 / imgW))} /> {thumbLoaded && ( <Image style={Object.assign({ display: loaded ? 'auto' : 'none' }, style)} lazyLoad className='image--is-loaded' mode='aspectFill' src={imgU} onLoad={this.toggleOriginLoaded.bind(this)} /> )} </Block> ); } 复制代码
以上为主要视图层和逻辑层代码,其中compressImage
函数是用来处理图片剪裁也就是缩略图的生成的,(ps:咱们是用nginx
实现的动态压缩,裁剪等功能,有须要的小伙伴能够自行搜索相关教程~)markdown
主要逻辑处理完成以后咱们再来看模糊样式的处理,在此就要介绍一个 css
方法 blur()
。框架
blur()
CSS
方法将高斯模糊应用于输出图片。它只有一个接受一个参数blur(radius)
函数
radius 表示模糊的半径,值为length。 它定义了高斯函数的标准误差值,即屏幕上有多少像素相互融合; 所以,较大的值会产生更多模糊。 值为0会使输入保持不变。 该值为空则为0。(来自MDN) 它能够生成相似毛玻璃样式的图片,以下图:动画
了解了这个方法以后,就让咱们来愉快的玩耍(写代码)吧~ 咱们能够给这个效果添加一个小动画,让它看起来更有意思哦~this
.image--not-loaded{
// fix ios 缺乏重绘的问题,添加无心义的transform强制触发重绘
transform: scale(1);
filter:blur(30px);
}
.image--is-loaded{
// fix ios 缺乏重绘的问题,添加无心义的transform强制触发重绘
transform: scale(1);
filter:blur(20px);
animation: sharpen 0.8s both;
}
@keyframes sharpen {
0% {
filter: blur(20px);
}
100% {
filter: blur(0px);
}
}
复制代码
须要注意的是blur方法在ios上会出现没法正确展现的问题,查询了相关文章后发现是由于ios 缺乏重绘,就是ios不会根据这个代码从新绘制页面所以不能正确展现,若是要解决这个问题只要给他加上一条没有意义的transform,强制触发重绘就能够了~~
效果图以下: 5571f524-1f57-43da-