導語
最近在做的小程式專案設計大量圖片的展示,小程式已經提供了圖片的懶加載功能,但是由於圖片本身比較大加上要展示的圖片比較多,如何以一個比較友善的方式展示未載入完成的過程就是一個必須解決的問題了。
想法
由於小程式沒有提供Image 這個js 對象,所以在小程式中實作預載不能直接像原生js 一樣,直接使用new Image()建立一個圖片對象,只能在視圖圖層建立圖片,透過onLoad事件監聽圖片載入完成。
實現圖片模糊載入的想法就是先載入一個目標圖片的縮圖,縮圖的載入一般非常快可以忽略不計,縮圖載入完成之後以高斯模糊的形式展示,同時載入原圖,原圖載入完成後替代原縮圖,原圖和縮圖需要設定相同的寬高。 思路理清楚之後,開始碼代碼吧~
由於專案使用了Taro框架,下面的程式碼寫法是React的寫法,原生或其他框架也可以參考,沒有太大的出入,思路都是一樣的。
imgLoader.js(以下為部分程式碼)
// 监听原图加载完成 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實現的動態壓縮,裁剪等功能,有需要的小伙伴可以自行搜索相關教程~)
主要邏輯處理完成之後我們再來看模糊樣式的處理,在此就要介紹一個css 方法blur()。
blur() CSS方法將高斯模糊套用到輸出圖片。它只有一個接受一個參數blur(radius)
radius 表示模糊的半径,值为length。 它定义了高斯函数的标准偏差值,即屏幕上有多少像素相互融合; 因此,较大的值会产生 更多模糊。值为0会使输入保持不变。 该值为空则为0。(来自MDN)它可以生成类似毛玻璃样式的图片,如下图:
了解了這個方法之後,就讓我們來愉快的玩耍(寫代碼)吧~ 我們可以給這個效果加上一個小動畫,讓它看起來更有意思哦~
.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,強制觸發重繪就可以了~~
推薦教程:《 微信小程式》
以上是小程式實作圖片模糊預載的詳細內容。更多資訊請關注PHP中文網其他相關文章!