更新cpp邀请函的过程经验分享

Apr 24, 2024

前言

本团队在一轮考核过后又(?通过网页的形式发出了一轮考核通过的网页邀请函,在去年师兄们制作网页的基础上修改了一些地方,主要是实现了一些自己的想法。

如果还没看过效果的可以来这个链接看一下效果:https://cppinvite.shiinafan.top/

如果对粒子效果的实现比较感兴趣的推荐看一下去年师兄写的文章,里面是他们尝试实现粒子效果的整个过程。基于 ThreeJs 实现的网页 3D 粒子效果经验分享 (qq.com)

当然师兄的代码仓库也在去年师兄写的文章里面。

简单 QA

Q: 背景的粒子特效是怎么做到的?

A:背景使用的是网页的 Webgl 技术,并使用封装好的 Threejs 渲染库制作。由于 Threejs 版本更新,许多 API 与模型使用方法也都发生了重大变化,所以额外需要花时间进行调整处理。

**Q**: 模型是怎么做的?

**A**:和普通的建模一样,本团队使用 Blender 进行模型建模,直接导出 obj 扩展名的模型进行处理,当然也可以使用其他格式的模型

Q: 如果要学习本项目需要先学习的技术栈是啥?

A:项目模板使用 React + Typescript + Threejs 进行制作,但是项目核心是纯 Threejs,对于 Threejs 只需要学习了基础即可进行本项目的学习

**Q**: 背景音乐?**A**:https://www.bilibili.com/video/BV1eW4y1v7ak/?t=63****

今年修改的地方

加载页

去年这个加载页只有 logo 文字、加载进度条、和进入页面的按钮。今年将进入页面的事件绑定在了整个页面上,同时进度条尝试使用了 svg 动画的形式来呈现。在方块顶端会有显示进度的数字,在完成后会淡化消失,同时点击任意处进入的提示会出现。~~总而言之就是多了花里胡哨的动效~~

26b41b39-3797-4f1e-b9c3-946ba1ba0559

加载中的时候:

8fa338de-0007-477e-920a-ac35f4f68fe7

方向选择的页面

去年方向选择是通过 5 个二维的光球按钮实现的,在移动端的排版会有点~~奇怪~~,所以我尝试使用 3d 效果去弥补客户端屏幕大小差距所导致不一样的视觉体验。这部分由 css3d 和用 react 手搓的拖曳代码实现,没有引入别的功能库,~~但是手搓懂得都懂~~。

1130e271-f726-4c41-a448-072758d97f15

其他一些改动

方向选择页面底下的漩涡模型改用了 obj 模型,意图通过细分曲面来使粒子更加密集,取得了一定成果,但是还是不能达到原网页的那种视觉效果。当然为了使粒子更密集也生成了更多的粒子,对比两年的效果不难发现这一点。其他的小改动无非就是改一下文字和图标,在这里就不对赘述了。

修改的想法和过程

想法

去年收到这个邀请函的时候就被这个网页所表现出来的视觉效果折服,感觉这种通知形式非常有意思。加上本来就对网页的 3d 效果有点兴趣,所以比较早的时候就下载了师兄的代码进行学习。又碰巧前段时间要做的一个项目有用到 three.js,所以基本上在做这个修改前的一段时间里对这个项目了解是比较系统的了。虽然那会时间安排上比较紧张,但还是决定挤一些时间出来延续一下邀请函这个做法。

当然这时候也是在学习师兄这个项目的过程中有了一些改进的想法,所以趁这个机会来试着实现一下。

过程

一开始做的改动与尝试比最后实现的要多得多,包括在加载页继续加上更多动画效果、把开场的粒子效果整一个重制之类的,在加载页代替加载条的方块其实本来是打算直接转到 3d 的粒子模型开始动画演出,但是后面对比过后发现还是原来的开场效果更加好看,权衡了一下时间和最终的效果,最终还是选择了放弃这个改动。

01c37cca-cfd6-4414-8e41-f0a7184e4147

至于加载页为什么不搞动画了,一大原因是确实时间比较赶,然后就是感觉再加动画就可能过于花里胡哨了,毕竟当时没有什么比较简洁的动画效果的想法,所以最终版的进入还是和去年一样的加载页元素淡出。

方向选择页面的效果

后面的尝试就是方向选择页面的效果了,毕竟构思的时候发现这样来解决移动端 ui 不太和谐的问题比较完美。在结构上,偷懒用了去年师兄已经写好的按钮组件,所以相当于 3d 层是套在这些组件外面的。当然这样做也带来了一些比较不方便的地方,比如由于牌上的元素比较多,所以在父组件里我要往子组件传好几个参数来使这个相同的组件渲染出不一样的图案。

这样的改动使得原本 1 行写完的代码变成了……5 行。

当然要是只是说这个 3d 效果还是比较好实现的,在最外层元素中设置视角距离,中层元素开启 3d 模式,内层元素使用绝对定位使他们能正确排列,最后通过对内层元素设置旋转的角度值与相对中心的偏移值就完成了。

外层 css 代码

706247e9-d7bb-4715-aefd-bbfa1c0b47d4

中层 css 代码

a052e5f2-276a-41b4-b7c5-f7c57c689da1

内层样式代码设置(因为每个内层元素要做的变化不同,所以直接在组件中使用了模板字符串来赋值)

ff8b10d0-bcc0-4d63-96a5-856be324d969

这里发现 css 的 3d 和 three 也是类似的,执行改变角度或者位置的代码是有先后顺序的,要按照实际需求来决定代码的顺序,例如这里就是要实现先旋转,后偏移,所以旋转的代码要放在偏移前面。

这样做完之后相当于你创建了一个正五棱柱,然后在五棱柱的每一个侧面都放置了一个元素。后续的拖曳旋转效果也不是根据鼠标的位移分别修改每一张牌的位置,而是直接修改正五棱柱的角度,这样我们可以更加容易地去操作这个界面。

说到拖曳的逻辑,又不得不提手搓的这回事,正常来讲都使用框架进行开发了,这些常用的逻辑都可以去找一些第三方包去实现,但是我当时觉得这个 3d 的逻辑多少和第三方包有点区别,而且也觉得这样一个小功能应该花不了多久,所以选择了自己在 React 组件中手写这个逻辑。结果就是一言难尽,刚写好的时候就有组件重新挂载引起重复设置监听的问题和不能正确获取响应式值的问题。

重新挂载出现 bug 的问题通过加了一堆条件判断基本解决了,这当然不是最好的解决办法,但是时间不充裕的情况下也只能先这样。

不能正确获取响应式变量的值其实也是在 React 中编写较为复杂的交互时容易遇到的问题,React 的响应式变量会随着值的改变而重新渲染页面与这个变量值相关的的部分,但是要是想通过这个变量读取现在页面的状态值,则只会读取到初值。要解决这个问题的话就要通过回调函数来输出暂存这个值,由于组件中对拖曳的判断函数使用回调会有新的 bug,所以这里从网上学习了一个包装后可以读取到值的写法:ef3f475e-9bc1-4042-afe2-e7f1cc48813f

使用起来倒是没什么问题。当然这部分的问题都是我个人的学习理解,我对在 React 编写较为复杂的交互经验不是很多,如有纰漏,敬请指正。

这个模块其实一开始打算写成复用程度比较高的模块而使用的,最后还是因为工期而妥协了,要是什么时候我觉得还是有必要去构建一下的时候再说吧。

模型的修改以及导入

除了今年的漩涡模型更换成了 obj 以外,其他的模型也进行了一些更换或者修改,包括我们的队标,去年标志仅有描边的模型,今年拜托 ui 把实体也填充上去了,据说做这个修改还是花了很大功夫的,其中也遇到了一些奇怪的 bug,有机会也让 ui 来分享一下吧(

至于导入的方面,师兄去年其实已经把导入资源的模式做的很清晰了,基本上只要修改一下导入资源的路径就可以使用了,当然要是体积和以前有区别的模型还是要手动调节一下位置和缩放的(比如标志)。总之这部分的修改也就这样,其实就算是我把开场动画替换掉也不会很费劲,毕竟师兄的代码其实写的很清楚了,加上我前期也花了时间去学习了这个项目,只能说暂时是没有更加有意思的效果去替换开场动画了。

二维码的话是进行的平面建模,这里主要是要使用旧版微信生成的二维码,然后用 96*96 的网格图去勾勒,新的二维码还没有进行过实验,新的二维码方块比较小,感觉会比旧版的群二维码更难用粒子来构成实现。

svg 动画

上面也提到过,这个页面其实玩了挺多的 svg 路径动画的,效果可能看上去比较难实现,实际上实现这个远比想象中的要简单。只需要懂一点 svg 标签的知识和 css 动画就可以复刻这些效果了。相比直接放 gif 图来说,一个是清晰度比较容易保证,一个是可以自由设置动画的形式,甚至使用一些 js 对动画实现一点交互(比如加载页的方块进度条)。

接下来就是具体的实现,首先要处理一下 svg 资源,使图标失去填充,同时调整路径的粗细程度。具体来讲就是这些属性:8de61772-dd6a-4a46-a958-bad0364f527b 分别对应失去填充,路径颜色,路径宽度,在 svg 标签中也有对应的属性。当然有些图标不需要额外设置填充,具体要看各个图标的差异。

接下来就是让路径动起来,实现路径动画,首先我们可以在控制台获取已经在页面上的 svg 图标路径长度(注意是要获取 path 标签对其使用 getTotalLength):

0806afe8-85be-4ed6-b11f-58e1973cdf3e

然后我们就可以去设置 css 动画了:

f8af80b9-112d-48fb-9cf6-519a70d75fad

这里我在标签上设置了初始值为 0,2566,所以这里直接设置动画完成后的状态就好。如果要实现牌面图标的效果,设置 stroke-dashoffset 的动画就好了,这里大家可以自己去尝试一下。基本的实现就这么简单。

结语

虽然修改这个项目花的时间林林总总也就五六天,但是我感觉我还是从自己动手去修改这个过程中学到了很多东西的。相比以往我学习这个项目去思考怎么复刻上面的某个效果,还是自己真正动手去修改时来的理解比较深。

其实原计划是我们另起炉灶,重新写了一个我们这一届的招新邀请函的,但是从计划初到最后有不少的突发情况,导致人手和时间都不是很多。加上后面有段时间我也创意破产(所以就由我开始来修改一个这个项目了。

当然也有其他小伙伴来帮助我去实现这个修改的想法了,就像是 ui 提供的模型和卡牌牌背,真的画的超赞。还有其他人帮忙去做二维码的模型,没有你们的帮助,或许我就很难完成这个修改了。