干貨 | 如何實現小程序圖片模糊預加載?

導語

最近在做的小程序項目設計大量圖片的展示,小程序已經提供了圖片的懶加載功能,但是由于圖片本身比較大加上要展示的圖片比較多,如何以一個比較友好的方式展示未加載完成的過程就是一個必須解決的問題了。

思路

由于小程序沒有提供 Image 這個 js 對象,所以在小程序中實現預加載不能直接像原生js 一樣,直接使用 new Image()創(chuàng)建一個圖片對象,只能在視圖層創(chuàng)建圖片,通過onLoad事件監(jiān)聽圖片加載完成。

實現圖片模糊加載的思路就是先加載一個目標圖片的縮略圖,縮略圖的加載一般非??炜梢院雎圆挥?,縮略圖加載完成之后以高斯模糊的形式展示,與此同時加載原圖,原圖加載完成后替代原縮略圖,原圖和縮略圖需要設置相同的寬高。 思路理清楚之后,開始碼代碼吧~

由于項目使用了Taro框架,下面的代碼寫法是React的寫法,原生或者其他框架也可以參考,沒有太大的出入,思路都是一樣的。

imgLoader.js(以下為部分代碼)

    // 監(jiān)聽原圖加載完成
  toggleOriginLoaded() {
    this.setState({
      loaded: true
    });
  }
  // 監(jiān)聽縮略圖加載完成
  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實現的動態(tài)壓縮,裁剪等功能,有需要的小伙伴可以自行搜索相關教程~)

主要邏輯處理完成之后我們再來看模糊樣式的處理,在此就要介紹一個 css 方法 blur():blur() CSS方法將高斯模糊應用于輸出圖片。它只有一個接受一個參數blur(radius)

image

了解了這個方法之后,就讓我們來愉快的玩耍(寫代碼)吧~ 我們可以給這個效果添加一個小動畫,讓它看起來更有意思哦~

.image--not-loaded{
  // fix ios 缺少重繪的問題,添加無意義的transform強制觸發(fā)重繪
  transform: scale(1);
  filter:blur(30px);
}
.image--is-loaded{
  // fix ios 缺少重繪的問題,添加無意義的transform強制觸發(fā)重繪
  transform: scale(1);
  filter:blur(20px);
  animation: sharpen 0.8s both;
}
@keyframes sharpen {
  0% {
    filter: blur(20px);
  }
  100% {
    filter: blur(0px);
  }
}

需要注意的是blur方法在ios上會出現無法正確展示的問題,查詢了相關文章后發(fā)現是因為ios 缺少重繪,就是ios不會根據這個代碼重新繪制頁面因此不能正確展示,如果要解決這個問題只要給他加上一條沒有意義的transform,強制觸發(fā)重繪就可以了~

效果圖如下: 5571f524-1f57-43da-

image

原文作者:Rolan

原文鏈接:http://www.wxapp-union.com/article-5815-1.html

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容