Introduction:

Recently in the small program project design a large number of picture display, small program has provided the lazy loading function of pictures, but because the picture itself is relatively large and there are more pictures to show, how to show the loading process in a friendly way is a problem that must be solved.

Train of thought

Since the applet does not provide the JS object Image, the applet can not directly use new Image() to create an Image object like the native JS, but can only create the Image in the view layer, through the onLoad event to listen for the Image load.

Realize image fuzzy load train of thought is to load a target image thumbnails, thumbnails load generally very fast negligible, thumbnail in the form of a gaussian blur after completion of loading, at the same time to load the original image, the original image after completion of loading replace the thumbnail, the original image and the thumbnail high need to set up the same width. After thinking clear, start code code ~

Since the project uses the Taro framework, the following code is written as React. Native or other frameworks can also be referred to. There are no big differences and the ideas are the same.

Imgloader.js (part of the code below)

// Listen for the original image to finish loadingtoggleOriginLoaded() {
		this.setState({
			loaded: true}); } // Listen for the thumbnail to loadtoggleThumbLoaded() {
		this.setState({
			thumbLoaded: true
		});
	}
	
	render() {
		let { loaded, thumbLoaded } = this.state;
		let{ imgU, imgW, imgH } = this.props; // Set the width and height of the thumbnail and original image based on the width and height passed inlet 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>
		);
	}
Copy the code

This is the main view layer and logic layer code. The compressImage function is used to process image clipping, which is the generation of thumbnail images.

After the main logic processing is complete, we will look at the processing of blur styles. Here we introduce a CSS method called blur ().

Blur () The CSS method applies gaussian blur to the output image. It only takes one parameter blur(radius)

Radius indicates the fuzzy radius. The value is length. It defines the standard deviation of the Gaussian function, that is, how many pixels on the screen merge with each other; Therefore, larger values create more ambiguity. A value of 0 leaves the input unchanged. If this value is null, it is 0. (from MDN) it produces a ground-glass-like image, as shown below:

Now that we know how to do this, let’s have some fun. We can add a little animation to this effect to make it look more interesting

.image--not-loaded{// fix ios is missing redraw problem, add meaningless transform force redraw transform: scale(1); filter:blur(30px); }. Image --is-loaded{// fix ios: transform: scale(1); filter:blur(20px); Animation: sharpen 0.8 s to both; } @keyframes sharpen { 0% { filter: blur(20px); } 100% { filter: blur(0px); }}Copy the code

It should be noted that the blur method cannot be displayed correctly on ios. After checking relevant articles, IT is found that ios lacks redrawing, that is, ios does not redraw the page according to this code, so it cannot be displayed correctly. To solve this problem, add a meaningless transform to it. Force trigger redraw will do

The renderings are as follows: 5571F524-1F57-43DA –