小程序实现图片模糊预加载


本文摘自PHP中文网,作者hzc,侵删。

导语


最近在做的小程序项目设计大量图片的展示,小程序已经提供了图片的懒加载功能,但是由于图片本身比较大加上要展示的图片比较多,如何以一个比较友好的方式展示未加载完成的过程就是一个必须解决的问题了。

思路


由于小程序没有提供 Image 这个 js 对象,所以在小程序中实现预加载不能直接像原生js 一样,直接使用 new Image()创建一个图片对象,只能在视图层创建图片,通过onLoad事件监听图片加载完成。

实现图片模糊加载的思路就是先加载一个目标图片的缩略图,缩略图的加载一般非常快可以忽略不计,缩略图加载完成之后以高斯模糊的形式展示,与此同时加载原图,原图加载完成后替代原缩略图,原图和缩略图需要设置相同的宽高。 思路理清楚之后,开始码代码吧~

由于项目使用了Taro框架,下面的代码写法是React的写法,原生或者其他框架也可以参考,没有太大的出入,思路都是一样的。

imgLoader.js(以下为部分代码)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

   // 监听原图加载完成

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)

1

2

radius 表示模糊的半径,值为length。 它定义了高斯函数的标准偏差值,即屏幕上有多少像素相互融合; 因此,较大的值会产生

更多模糊。值为0会使输入保持不变。 该值为空则为0。(来自MDN)它可以生成类似毛玻璃样式的图片,如下图:

0.png

了解了这个方法之后,就让我们来愉快的玩耍(写代码)吧~ 我们可以给这个效果添加一个小动画,让它看起来更有意思哦~

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.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,强制触发重绘就可以了~~

推荐教程:《微信小程序》

以上就是小程序实现图片模糊预加载的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

如何在微信小程序中显示html格式内容(图文教程)

小程序代码构成

小程序中canvas如何实现图案在线定制的功能

h5和小程序有什么区别

开始

微信小程序简单介绍

小程序学习之如何获取地理定位并显示城市名称

小程序实现图片模糊预加载

小程序简介

canvas实现九宫格心形拼图的方法(附代码)

更多相关阅读请进入《小程序》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...