Watcher

一个图片预览网站

2019-12-17

我喜欢旅游,偏向自然风光的旅游,但我是一个程序员,到目前为止,大多数时间只能在办公室里度过,所以在我很累或者很闲的时候,我总是习惯去看看风景图片,遐想着有一天我能去那些地方旅游。

003

国内的网站都商业化比较严重,质量高又免费的比较难找,思来想去,还是自己做一个。正巧一个好朋友在学习瀑布流布局方式,然后我突发奇想说来一场比赛,看谁能更快的构建一个瀑布流网站,所以这个网站应运而生。

还是先说一下诉求,我希望做一个可以看高质量图片的网站,图片能自动更新,加载方式用瀑布流,网站整体要比较清爽、极简。好像就这么多,让我们开始吧。

因为这个网站的核心技术点是数据源跟瀑布流布局,所以这篇 blog 重点说这两个事情。

数据源

数据源的问题我找了比较久,最开始打算用 https://picsum.photos/ 这个数据源,但后来在使用过程中发现图片更新比较慢,而且如果用随机的方式的话要自己考虑去重问题,就放弃了。最后找来找去,还是选择用 https://unsplash.com/ ,主要是它的图片质量跟更新频率都很优秀,然后图片都是免费的,不会有版权问题。但伴随而来了一个新问题,图片读取速度。

桥接数据

因为 unsplash 的站点在国外,所以在国内打开会很慢,好像没有很好的解决这个问题的办法,我最终用了一个很蠢的办法,利用自己的 vps 做一个桥接。简单来说就是我在我的 vps 服务器上起了一个服务,通过这个服务器做数据流的桥接,这样图片访问速度就达到了一个可以接受的程度。核心代码如下:

app.get("/api/xxx", (req, res) => {
  request.get(req.query.path).pipe(res)
})

看起来很简单,其实它确实很简单,使用 request 这个库就能轻松实现这个过程。

瀑布流

数据问题解决后就开始解决第二个核心问题,瀑布流。

用瀑布流关键字去搜索可以很容易的搜到一些解决方案,这些解决方案中最简单的应该算是 column-count 解决方案,利用 column-count 的特性,你可以很快的实现一个瀑布流,但在实践中我发现这个方案其实是有问题的。

.demo {
  column-count: 3;
}

瀑布流的目的是在数据加载的时候用像瀑布的方式加载数据,又称砌砖布局方式,就像这样:

1  2  3
4  5  6
7  8  9

column-count 的机制确是这样:

1 (4) 7
2  5  8
3  6  9

当有新的数据后

 1  5  9
 2  6  10
 3  7  11
(4) 8

你会发现这种排版方式其实不符合我们阅读习惯。再尝试了其他几种方式后,我最终选择了一个比较笨,但比较好理解的方式 - flex 布局方式。

flex 布局方式最大的好处就是简单、方便控制,只要把展示的图片分位 N 个数组,每个数组会记录当前数组渲染后的图片高度之和,然后在每次有新的图片的时候,优先添加早高度最小的数组里去,这样就实现了瀑布流。就像这样:

const oneLine = {
  height: 100,
  photos: [1, 4],
}

const twoLine = {
  height: 180,
  photos: [2, 5, 7, 9],
}

const threeLine = {
  height: 150,
  photos: [3, 6, 8],
}

当有新的图片10的时候,通过便利当前所有数组,找出高度最小的数组,然后添加进去。然后页面上就很简单的使用 N 个 div,然后纵向排列就好了。

yang_blog_photos_001.gif

总结

看起来写的内容不是很多,其实做这个网站过程还是很曲折的,从最开始的数据源选择,到后来的瀑布流布局,都尝试了各种方法后才找到了合适的,似乎所有的事情都是这样?总要在实践中才能找到适合自己的东西。

在这里讨论

后记

由于没有审美细胞,这个网站的样式很简陋,所以我请了一个朋友帮忙设计一下这个网站,目前还在设计中,等有结果了我把改造过程再更新到这篇 blog 里。

别忘了这是一场比赛,这是另外一位选手的作品: 地址


Yang

Yang的个人博客
我在这里记录我的生活