Introduction
The mini program project I am working on recently is designed to display a large number of pictures. The mini program has provided the lazy loading function of pictures, but because the pictures themselves are relatively large, There are many pictures to be displayed on the website. How to display the unfinished loading process in a friendly way is a problem that must be solved.
Ideas
Since the mini program does not provide the Image js object, the preloading in the mini program cannot be directly used like native js, using new Image() creates an image object. It can only create images in the view layer and monitor the image loading completion through the onLoad event.
The idea of implementing image blur loading is to first load a thumbnail of the target image. The loading of the thumbnail is generally very fast and can be ignored. After the thumbnail is loaded, it will be displayed in the form of Gaussian blur. At the same time, the original image will be loaded. After the original image is loaded, it will replace the original thumbnail. The original image and the thumbnail need to have the same width and height. After the idea is clear, start coding~
Since the project uses the Taro framework, the following code is written in React. You can also refer to native or other frameworks. There is not much difference. Ideas all the same.
imgLoader.js (the following is part of the code)
// 监听原图加载完成 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> ); }
The above is the main view layer and logic layer code, in which the compressImage function is used to process image cropping, that is, the generation of thumbnails. (ps: We use nginx to implement dynamic compression, cropping and other functions. Friends in need can search for relevant tutorials by themselves~)
After the main logical processing is completed, let’s look at the processing of fuzzy styles. This is about introducing a css method blur().
blur() CSS method applies Gaussian blur to the output image. It only accepts one parameter blur(radius)
radius 表示模糊的半径,值为length。 它定义了高斯函数的标准偏差值,即屏幕上有多少像素相互融合; 因此,较大的值会产生 更多模糊。值为0会使输入保持不变。 该值为空则为0。(来自MDN)它可以生成类似毛玻璃样式的图片,如下图:
After understanding this method, let us have fun (writing code) ~ We can give this effect Add a small animation to make it look more interesting~
.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); } }
It should be noted that the blur method will not be displayed correctly on ios. After querying related articles, I found that it is because ios lacks redrawing. That is, iOS will not redraw the page based on this code, so it cannot be displayed correctly. If you want to solve this problem, just add a meaningless transform to it and force the redraw to be triggered~~
Recommended tutorial: " WeChat Mini Program》
The above is the detailed content of Mini program implements image blur preloading. For more information, please follow other related articles on the PHP Chinese website!