我几乎每年都会更新一版个人网站。在 2017 年上一次改版的时候,我曾经很狂妄的放出话说:「这次的设计可能以后都很难突破了怎么办?」

果然我在 2018 年并没有更新个人网站的设计……

好在 2019 年不用再交上白卷。

下面就和大家一起来分享一下我用了 10 个月完成的像素复古风个人网站的技术实现,以及 6 年半建站经验的心得。

从 2013 年 1 月我正式在 GitHub 上新建了个人网站,2 月份我购买了 zhangwenli.com 的域名,至今已经有 6 年多的时间了。当初之所以每年都会更新一版的设计,主要也是因为每年都会有不同的想法,再加上新看到的一些设计思路以及在编程技术方面的成长,都会让我萌生想要更新个人网站设计的想法。所以说,更新个人网站可能并不是一个给自己的计划。

不过我很高兴能看到,这么多年来通过自己持续的改进,个人网站和自己的技术能力都能有所提升。其实在每年设计的时候,基本上都是对自己的作品比较满意的,相反,倒是过了这么多年之后,回过头去看自己的作品,才会发现到有哪些不足的地方。所以这篇文章一方面是想要和大家分享一下今年设计中的技术实现思路的干货,另外一方面也是想要回顾一下在往年的作品中的不足之处。

接下来的文章我会首先介绍一下,今年的这一版设计中的设计思路和技术实现的小技巧;然后如果大家感兴趣的话,我也会再分享一下,在制作过程中的小故事。

2019 版个站的技术干货分享

很多人可能会感兴趣,这个像素画是怎么画出来的。但其实它可以分为几个不同的部分,每个部分的技术实现都不太相同,那么接下来我就会分别介绍一下。

像素风应用图标

首先我想讲一个最没有技术含量的部分,就是——应用图标的像素风格是怎么制作的。

它的答案很暴力,就是——是在 Photoshop 中一个一个像素画出来的。

会不会有些失望?我们作为程序员可能很多时候都会从技术实现的角度去思考问题,不过重要的不是通过什么技术解决,而是怎样能实现最好的效果。如果手绘的效果是最好的,那么我就会选择手绘。事实上我的确可以通过一些自动化的方法去生成这样的图片,但但效果肯定没有手绘的好,而这些图片是个人网站设计中,几乎最关键的部分,所以一定要花心思把它们通过手绘的方式画好。

上面这张截图是大家看到的,网站上的实际效果。而下图则是我在 Photoshop 中实际画的图片(真实大小)。

大家在这张图片中看到的一个最小方块就是实际的一个像素。在 CSS 中我会把这个图片通过背景图片应用到 App 上,并且进行缩放。在缩放时设置了 CSS 样式 image-rendering: pixelated;,使得缩放的过程中采取了最近邻缩放(也就是使用它最接近的像素点去插值)。通过这样的效果,图片在放大之后就会保留像素的风格,而不会被周围的像素模糊化。

在绘制的过程中,我我会把按钮的地图放在我要绘制的图标下方作为参考,这可以让我知道绘制的结果。

实际在保留图片的时候只保留了按钮的内容部分,并没有保留按钮的样式。按钮部分被保存在一张单独的图片中,用来实现按下按钮的效果。通过将按下按钮时,改变背景图片的方式就能实现按钮按下的效果了。

像素风相册缩略图

我想分享的第二方面的技术实现是相册部分。

相册部分因为图片的颜色各异,很难保持和整体一致的风格。因此在缩略图的时候,我就写了一个脚本,将图片生成出一张和整体颜色相同的图片。

这部分的代码也开源在 https://github.com/Ovilia/sunglass,大家感兴趣的话,可以自己查看一下源码。

基本的思路是,将图片中的每一个像素点,找到我给定的调色板(palette)中最接近的一个颜色,然后将其替换。

大家如果观察仔细的话,还会发现这种算法,虽然简单,但是对一些图片的效果可能不是很好,比如说有的图片可能出现全白的现象。这个可以写个改良版的颜色均衡化处理(对应调色板颜色的均衡化),不过其实不是很影响所以我就没实现。

至于打开图片后,出现的马赛克消失的效果就非常简单了。将图片上方覆盖一个白色的 Canvas,然后通过动画,每次随机地擦除一些方块,就能实现这一效果了。

像素风边框生成

可能大家不会想到的是这个网站技术难度最高的,其实是一个大家很容易忽略的细节,那就是像素边框的生成。

没错,就是这样,一个像素宽的圆角边框。

先给大家两分钟,自己思考一下,如果让你实现这样的边框有什么办法呢?需要注意的是,由于它会作用于各种不同的对象,所以它的大小是不固定的。圆角的大小也是不固定的。

我不知道有没有更简单的实现方式,如果大家想到的话也可以告诉我。我实际采用的方式是,通过绘制 Canvas,得到包含像素边框的图片,然后将这个图片作为背景图。那么算法最关键的部分就是如何通过 Canvas 生成这样的像素边框。为了尽可能的减少资源,和之前图标的背景图的想法是相同的,大家看到的一个小方块就是一个像素点,然后通过缩放和设置 image-rendering: pixelated; 生效。具体的情况可能很复杂,比如说有的时候我们希望左上角没有圆角,而其他三个角,有不同的,半径的圆角。虽然说他是技术难度上最复杂的,但其实也就是一些仔细的计算,只要知道了拐角处的路径,那么就是通过路径绘制就可以了,只是算的时候需要非常认真细心。

聊天机器人

2017 版的设计就有人提问是如何实现聊天机器人的效果。当时我的实现方案是写了一个 JSON,在这个文件中定义了所有可能的问题和答复,以及当用户答复时我的反馈。用户只能在其中选择一个回答,因此所有的聊天路径都是可预知的,我只要根据用户的回答找到对应的答复的条目就可以了。

今年这一版的设计优化了一下这一方案,但它在本质上也是相同的,只不过在实现层面更加方便一些。去年我自己定义的这个格式,其中有一个最大的问题是,我用ID规定了相应的答复条目,但是当这个文件非常长的时候,我在编辑的时候,其实已经很难上上下下的找到他对应的地方,而且自己手写 JSON 很容易出错。

在今年的这一版中发现了一个很好用的工具叫做 Inky。他本来是用在叙事游戏中生成脚本的,但是对我的这个应用场景而言,恰好是可以使用的。

因此我只需要照着它的格式,就可以生成交互的路径,最终可以通过这个工具导出一个 JSON,并且使用 js 调用这个JSON,就能够实现路径的跳转。

不知道上面说的这些技术实现对大家有没有帮助呢,我觉得虽然这些技术很可能是我们在做业务的时候并不太会做到的需求,但是其中的一些思维还是可以借鉴的。总结一下,我觉得就 2019 年的这版而言,我做的过程中还是感觉到有一定的技术难度的,但是也没有多特别难,难到没有头绪。而最终组合在一起的效果看起来就会很复杂,感觉很高级。事实上,不过是别人没有尝试过把这些东西组合在一起而已。这样想的话,其实创新也并没有那么难。

接下来,我想介绍一下,为什么我会想到今年的这一版的设计风格。

2019 版构思

这两年我比较喜欢玩像素风格的游戏,这一点可能很大程度上也是受到了钰猫的影响。之前我觉得我也并不是很能接受像素风格的艺术。但是一旦了解了如何去欣赏的方法之后,就会发现,像素风其实是一种很典型的,用简洁的设计表现艺术的有效途径。

要说今年的这一版设计,就要先回顾到 2017 年的个人网站设计。2017 年的时候我设计了一款聊天交互型的个人网站,现在我们可以用一个词,聊天机器人,就能够很方便地让你理解到它的定位。

但是在当时,其实这样的产品并不是很多。而我之所以能想到这样子一个设计,主要是想要表达:在社交网络上,一个陌生人了解到的我,和我的微信好友,通过聊天了解到的我,这两者的差别,到底有多大呢?所以就想说,做一个个人网站,你可以通过聊天界面,就好像在和我交流一样。

这一版的效果很好,当然很大程度上也有赖于,聊天对话中我刻意添加了很多幽默的元素,使得这一个聊天机器人,并不像一般的机器那么冷血,会让人更加感觉像和真人在聊天。它的实现原理也很简单,就是通过一个 JSON 文件,把聊天的所有内容,都写在里面,用户能做的选择只是在这个预先写好的脚本中,做有限的选择。所以它并不是一个真正意义上的聊天机器人,因为你无法任意输入。但是这并不妨碍它成为一款有趣的个人网站应用。

因为我对 2017 年的这一版挺满意的,所以比较长的一段时间内都没有萌生想要去修改它的想法。之后在和钰猫讨论我如何还能再次改版我的设计的时候,就碰撞出了这个灵感——把我的个人网站做成一个手机应用!不同的 APP 就是了解我不同社交网站或者作品的入口——我觉得这是一个很有意思的想法,并且它还能和我 2017 年的这一版,聊天机器人结合在一起。

于是就开始一边设计,一边实现。最开始的想法是,模拟 iOS 手机的界面。我已经实现到了还原度比较高的效果,但是整体来讲并没有特别让人眼前一亮的地方——因为它毕竟太像我们熟悉的手机系统了。于是又经过了一段时间,我想到了,用当时比较感兴趣的像素风去实现手机系统。

我花了两个月的时间,基本上实现了想要的效果,剩下的工作量主要就是画像素画和添加文本内容。而我实际之后又花了 8 个月的时间完成这一部分的工作——当然主要是由于拖延症的关系。直到前几天的某一个晚上,我想继续画几个应用图标,用了两个小时,画了 6 个。然后不知道怎么突然意识到好像差不多就完成剩下的工作了,于是又花了一个小时完善了一下,居然这就发布了……

我不知道大家会不会这样,我个人的经验就是,有时候觉得一件事情剩下的工作量特别大,然后就不太想做,一直拖延着。但其实如果真的去做的话,会发现实际需要的时间也并不长。所以需要保持做下去的惯性,这一点很重要。

6 年 5 版个人网站心得

我觉得个人网站是一个很好的练手的平台,因为相比于设计其他产品可能受到各种因素的掣肘,个人网站就是一个非常私人的东西——你想要向大家怎么样表现自己,表现一个怎么样的自己,这个都是可以通过个人网站反映的。所以,一些很夸张、很过度的设计也可以应用到个人网站中——只要我喜欢!所以,不管你是前端工程师想要找个项目练练手,还是作为自己的作品得到别人的认可等等原因,做个人网站都是一个很好的方式。

最后我想谈一下,做了 6 年个人网站的一些心得。

2013

最初我在 2013 年做个人网站的时候,我本科还没有毕业,当时已经有一些做网页的基础了,想要把自己的综合能力运用起来,做一个能够表现自己特色的个人网站。于是当时我做了这样一个,我现在看起来已经是丑的不能接受的个人网站……大家看看小图感受下即可,或者访问 http://zhangwenli.com/2013

那时候我特别喜欢老子道德经之类的东西,于是这个网站的设计,也很大程度上来源于此。当然我现在去看的时候我会觉得有很多地方的设计非常的粗糙,也能提出一些简单却非常行之有效的方法对其进行改善,但是当时的我其实也是对自己的作品比较满意的,还提交了一个css的网站比赛……还拿了一个提名奖……

我觉得有一件非常有价值的事就是,在这么多年的不断改进设计中,绝大部分的设计都被抛弃了,但是每年都会留下一些我仍然觉得不错的东西,那么经过五六年的时间,沉淀下来的可能就是,我个人确实非常喜欢,或者我觉得有价值的东西。

比如说,就 2013 年的这一版而言,其中绝大部分的东西都被抛弃了,但是这个纸质的旋转的效果,一直保留到我今天的博客中仍然在使用。我接下来准备把博客的风格也改为和主页一致的像素风格,但是我仍然准备保留下这种纸片的旋转的效果。至于这种效果的技术实现,其实也非常简单,就是加两个额外的 DIV,对它们进行一定角度的旋转,使得它们看起来的效果就好像是底下的几两张纸,而又正好不露出来。

2014

2014 版的设计还是和道家思想有关,和光同尘源于「和其光,同其尘」这句话,通俗地讲就是和周围散发出相等亮度的光,不要过度张扬。

这一版的设计的想法就是通过鼠标的位置控制阴影的位置,然后就好像鼠标是一个光源一样,只有当鼠标靠近中心的时候才会看到文字。这也是与「和其光」的概念是相等的,你只有足够靠近的时候才能看到那个真正的我。

2015

2015 版的个人网站主要的设计思路是通过纯 CSS 的方式实现一个动态的样式转换,如果鼠标在左侧就会高亮左侧,如果鼠标在右侧就会高亮右侧。

2016

2016 版的设计比较有意思,它是一个通过 SVG 的动画实现的,绘制我的个人logo的效果。

小结

其实可以发现之前这几年的设计,都是一个比较小的创意的点,然后加了一些社交网站的链接,这样的设计。所以从 2017 年开始做比较复杂的聊天机器人,也算是一个突破吧!

那么 2020 版的个人网站会是什么样子呢?我也很期待,但是我现在不会像 2017 年那样担心说,觉得以后不能突破了怎么办?因为我知道随着阅历的增长,知识的积累,一定是能够想出更棒的创意的。

我还记得我在 2013 年的时候搜了很多,如何增长博客流量的方法。最后的结论是,最根本的还是能够持续地创造有价值的内容,并且需要一定时间的积累。其实子有句话曰得很好:「不患人之不己知,患不知人也」。如果自己本身不是一个有料的人,那么被再多人了解到的也不过是一个皮囊而已。如果自己的内心世界足够丰富,那么又何必在意,是不是被别人了解呢?

——这就是为什么我很久没写博客的原因吧?

PS:本文是我第一次尝试用语音识别的方式生成的文章,感觉比打字快很多,但是有时候可能有些错别字,请大家谅解。另外感觉打字和说话的文风也不太一样,我更喜欢打字的文风吧。你有没有感觉出区别呢?多多给我留言吧!