Skip to content

记录自己做的一个图片预览网站 #12

@programmer-yang

Description

@programmer-yang

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

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 里。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions