最近在作的小程序項目設計大量圖片的展現,小程序已經提供了圖片的懶加載功能,可是因爲圖片自己比較大加上要展現的圖片比較多,如何以一個比較友好的方式展現未加載完成的過程就是一個必須解決的問題了。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-