Home  >  Article  >  WeChat Applet  >  Waterfall flow in mini program

Waterfall flow in mini program

hzc
hzcforward
2020-06-19 10:59:562743browse

Waterfall flow is a very common web page layout. The visual performance is an uneven multi-column layout. It is a very popular layout form nowadays. I happened to encounter it recently when I was writing a small program. I thought of several different ways. Next, let’s take a look at the specific implementation method (the examples used in the methods are all two-column layouts).

Constant height waterfall flow

Constant height waterfall flow, as the name suggests, means that the height of a single box in the waterfall flow is the same. This form of waterfall flow is also relatively simple to implement, because It does not involve the calculation of the height of the box. Here is an example:

<view>
  <view></view>
</view>
Page({
  data: {
    list: []
  },
  onLoad () {
    let images = []
    for (let i = 0; i <pre class="brush:php;toolbar:false">.fall {
  display: flex;
  flex-wrap: wrap;
  background-color: #f7f7f7;
}
.fall-item {
  width: 330rpx;
  height: 330rpx;
  margin-top: 30rpx;
  margin-left: 30rpx;
  background-color: aquamarine;
}

For convenience, the box content in the example does not use pictures, but uses color blocks instead. The implementation of the equal-height waterfall flow can be directly done through flex Layout implementation, as shown in the example, directly use flex layout, allow line breaks, and set the width and height of each box in the waterfall flow to achieve a simple two-column waterfall flow layout

unequal height waterfall Flow

Unequal height waterfall flow is the more common form. Unequal height waterfall flow involves the calculation of column height. Since the height of each box is different, the column height of each column needs to be recorded. , compare, insert the next box into a column with a short height, and then let’s take a look at the implementation of unequal-height waterfall flow

Known box height

Generally, what is shown in the waterfall flow is It is a picture. In this case, the server will return the width and height of the picture to be displayed to the front end. In this case, it is relatively simple, because the server will return the width and height of the picture, and the front end only needs to calculate the column height. Just insert the next picture into the shorter column. For example:

<view>
  <view>
    <view></view>
  </view>
</view>
.fall {
  display: flex;
  background-color: #f7f7f7;
}

.fall-column {
  display: flex;
  flex-direction: column;
  margin-left: 30rpx;
}

.fall-column-item {
  width: 330rpx;
  margin-top: 30rpx;
  background-color: aquamarine;
}
Page({
  data: {
    images: [{
      width: 360,
      height: 540
    }, {
      width: 480,
      height: 540
    }, {
      width: 540,
      height: 720
    }, {
      width: 720,
      height: 960
    }, {
      width: 540,
      height: 960
    }, {
      width: 360,
      height: 720
    }, {
      width: 360,
      height: 960
    }, {
      width: 540,
      height: 540
    }, {
      width: 540,
      height: 1440
    }, {
      width: 960,
      height: 1440
    }],
    heightArr: [],
    list: [],
    col: 2
  },
  onLoad () {
    this.initData(2)
  },
  initData (col) {
    let images = []
    let scale = 2
    // 模拟图片宽高
    for (let i = 0; i <p> In the above example, color blocks are used to simulate the picture for convenience. The width and height of 10 pictures are simulated in js. Each Randomly select 10 pictures from it each time and define two columns. Calculate the height of each column each time, insert the picture into the shorter column, and then use the height array to record and accumulate the height of the picture. It is also very simple to implement </p><h3>Unknown box height</h3><p>What should we do if the box height is unknown? </p><h4>wx.getImageInfo</h4><p>The first way is to obtain the image width and height information through wx.getImageInfo. For example: </p><pre class="brush:php;toolbar:false"><view>
  <view>
    <view>
      <image></image>
    </view>
  </view>
</view>
.fall {
  display: flex;
  background-color: #f7f7f7;
}

.fall-column {
  display: flex;
  flex-direction: column;
  margin-left: 30rpx;
}

.fall-column-item {
  margin-top: 30rpx;
  line-height: 0;
}

.fall-column-item-img {
  width: 330rpx;
}
import api from '../../api/index'
Page({
  data: {
    list: [],
    heightArr: []
  },
  async onLoad () {
    let {results} = await api.fetchImages()
    let col = 2
    for (let i in results) {
      results[i].cover = results[i].imageUrl
      // 获取图片信息
      let info = await this.loadImage(results[i].cover)
      results[i].height = 165 / info.width * info.height
      if (i  {
      wx.getImageInfo({
        src: cover,
        success: (res) => {
          resolve(res)
        }
      })
    })
  }
})

When the server does not return the image When the width and height are specified, the image information can be obtained directly through wx.getImageInfo(). In order not to disrupt the order of the images when the service returns, this is specially sealed with a Promise layer, just to obtain one image after loading. Next picture, but when the picture is relatively large, it will take a long time to load and there will be a long white screen:
Waterfall flow in mini program

This is because wx.getImageInfo() obtains When obtaining image information, the image will be downloaded first, and then the image information can be obtained, which will take a longer time. However, if you do not need the image loading sequence, you can consider loading it directly in parallel, and load the next image before it is loaded. One picture, so that it can be displayed faster

wx.getImageInfo optimization

Since it takes a long time to load the image to obtain information, consider whether you can add a default image so that users can The first time you see the content display, you can display the image after getting the image information. For example:

<view>
  <view>
    <view>
      <image></image>
    </view>
  </view>
</view>
.fall {
  display: flex;
  background-color: #f7f7f7;
}

.fall-column {
  display: flex;
  flex-direction: column;
  margin-left: 30rpx;
}

.fall-column-item {
  position: relative;
  margin-top: 30rpx;
  line-height: 0;
  background-color: #ccc;
}

.fall-column-item::after {
  content: '加载中';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: inline-block;
  color: #666;
}

.fall-column-item-img {
  position: relative;
  width: 330rpx;
  z-index: 1;
}
import api from '../../api/index'
Page({
  data: {
    list: [],
    heightArr: []
  },
  async onLoad () {
    let {results} = await api.fetchImages()
    let col = 2
    for (let i = 0; i  {
      wx.getImageInfo({
        src: cover,
        success: (res) => {
          resolve(res)
        }
      })
    })
  }
})

In this example, a default loading display is given before the image is loaded. , of course, this is just a simple example and can only provide simple optimization ideas. The actual loading transition animation will definitely be designed more delicately

Cloud storage obtains user information

In general small programs The images used are all stored on the cloud server, and the cloud server generally provides parameters on the image request address to obtain image information. Taking Alibaba Cloud as an example, you can splice ?x-oss-process=image on the image link. /info, you can get the image information, for example:

<view>
  <view>
    <view>
      <image></image>
    </view>
  </view>
</view>
.fall {
  display: flex;
  background-color: #f7f7f7;
}

.fall-column {
  display: flex;
  flex-direction: column;
  margin-left: 30rpx;
}

.fall-column-item {
  position: relative;
  margin-top: 30rpx;
  line-height: 0;
  background-color: #ccc;
}

.fall-column-item::after {
  content: '加载中';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: inline-block;
  color: #666;
}

.fall-column-item-img {
  position: relative;
  width: 330rpx;
  z-index: 1;
}
let fetchPicInfo = async (url) => {
  let [err, result] = await to(testFly.get(`${url}?x-oss-process=image/info`))
  if (err) throw err
  return result.data
}
import api from '../../api/index'
Page({
  data: {
    list: [],
    heightArr: []
  },
  async onLoad () {
    let {results} = await api.fetchImages()
    let col = 2
    for (let i = 0; i <p>This method can greatly reduce the image loading time. There is no need to download the image locally to obtain the image information, but directly request the server. Image information, plus each request only returns a few fields of basic image information, so the request time is also very short, as shown in the figure: <br><img src="https://img.php.cn/upload/image/137/787/730/1592535565112393.png" title="1592535565112393.png" alt="Waterfall flow in mini program"></p><p> This way users can see the image faster display, and also adds a transition effect when the image is loaded, so that the experience will be better</p><h2>Summary</h2><p>This article describes the waterfall flow that I encountered recently when writing a small program. A more detailed summary. Choose different loading schemes under different circumstances. The best experience is of course that the server directly returns the image information. This can save a lot of time in obtaining image information and provide a better user experience. I hope it can It can be helpful to you when writing small program waterfall flow. <br><br>If there are errors or inaccuracies, you are welcome to criticize and correct me. If you like it, you are welcome to like it</p><p>Recommended tutorial: "<a href="https://www.php.cn/weixin-marketing.html" target="_blank">WeChat Mini Program</a>"</p>

The above is the detailed content of Waterfall flow in mini program. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete