这是一款由 Three.js 实现的镜头对着一间低多边形风格的办公室:地毯、格子隔断、天花板上一排排日光灯、背墙的百叶窗,两张对着摆的办公桌,中间是显示器和键盘。画面一开始,屏幕上就有一封邮件在逐字打出来,写完停顿一下、提示“正在发送”,然后跳出一条红色的投递失败提示——显示器被震得抖了两下,旁边的打印机指示灯开始闪,缓缓吐出一张退信通知。这时你可以点那张纸,它会当场揉成一个纸团,跟着鼠标走;再点一下就顺着甩出去的方向抛出,落进垃圾桶会计一分,撞到桶沿则弹开。一张纸投出去,打印机立刻再打一张,可以一直玩下去。
整个场景没有加载任何 3D 模型文件,桌椅、显示器、打印机、垃圾桶全部由代码堆基础几何体拼成,屏幕内容和退信通知则是用 Canvas 现场画好再当纹理贴上去的。
这段办公室退信动画里最值得拆的四处
屏幕上的邮件是画出来的,不是贴图。脚本开了一块离屏 Canvas,每帧重绘标题栏、收件人、正文、状态条,再作为纹理更新到显示器材质上,所以打字、发送中、投递失败三种状态可以无缝切换。
纸张揉成团是顶点形变。一张分段的平面网格预先算好一套“球面随机目标点”,揉纸时把每个顶点从原位插值到目标位,并重算法线——所以纸团的褶皱是立体的,不是换了个球体模型。
打印机吐纸用的是局部裁剪面。材质挂了一个 clippingPlane,纸还在机器里的那截会被真实裁掉,配合阴影裁剪,纸看起来是从缝里长出来的。
投掷手感来自速度采样。纸团被“握住”时每帧记录位移换算成瞬时速度并做平滑,松手时用这个速度作为初速——所以甩得快就飞得远,和真的甩东西一致。
三个让它显得“不像网页”的技术点
其一,揉纸的形变目标是提前算死的。初始化时脚本遍历平面的所有顶点,给每个点加一点随机偏移,再把它投影到一个半径带随机扰动的球面上,存成一份目标数组。之后揉纸只是在两组坐标之间做线性插值:
arr[i] = flat[i] + (tgt[i] - flat[i]) * a;
好处是每次揉出来的团都保持同一套褶皱,动画可逆、可暂停,也不用在动画过程中做任何随机运算。代价是每张纸的褶皱形状一样——但纸团在空中翻滚,观众几乎察觉不到。
其二,垃圾桶有“吸附”和“弹桶沿”两套判定。纸团下落时若接近桶口一定范围,会被施加一个指向桶心的横向加速度,帮玩家把边缘球收进去;但如果穿过桶口平面的那一帧落点位于内径与外径之间,就判定砸中桶沿,沿径向向外反弹并保留一部分能量。前者让手感宽容,后者保证失败也有反馈,两者缺一游戏性就垮。
其三,整段流程是相位驱动的。打字、停顿、发送、退信、打印、待取、揉纸、握持串成一条相位链,每个相位有自己的时长和退出条件。这种写法的好处是任何一步都能单独调时长,也很容易在中间插新环节,比如加一个“同事探头看过来”的镜头。
拿到源码后能改哪些
最常改的是文案:邮件正文写在一个常量字符串里(用换行符分段),标题栏、收件人、主题、失败提示分别是几行绘制调用;退信通知那张纸的所有文字集中在一个立即执行函数里,包括那枚倾斜的红框印章。把这些换成自己的品牌口径,整段动画的叙事就变了。
节奏参数散在主循环里:打字速度是一个每秒推进的字符数、停顿与发送阶段各自的秒数、打印吐纸的时长、揉纸的时长,都是能直接搜到的数字。想做成演示视频就整体放慢,想做成游戏就把前戏压短。
场景配色由一个材质工厂函数统一产出,地毯、天花板、墙面、桌面各自一行颜色;灯光是半球光加一盏带阴影的主光加环境光。做暗色办公室只要把主光调暗、把日光灯面板的自发光强度提上去即可。垃圾桶的位置、内外半径、重力大小也都是独立常量,直接决定投篮难度。
运行提示:脚本以 ES Module 方式从 CDN 加载 Three.js,必须用本地服务器打开,双击 HTML 会空白;内网部署需先把库文件放到本地并改导入路径。局部裁剪面需要浏览器支持较新的 WebGL 特性,建议使用近两年版本的 Chrome、Edge、Firefox 或 Safari。详细运行方法请参见压缩包内的帮助文档。
关于这个揉纸投篮特效的常见问题
能不能把邮件内容换成中文长文?
可以,正文常量直接改即可,注意每行长度——绘制是按换行符逐行输出的,不会自动折行,太长会超出屏幕区域。字体已经配置了中文回退,无需额外处理。
手机上能玩吗?
能。点击与拖拽都走 pointer 事件,触摸屏同样触发揉纸和投掷。只是场景对象较多且开了阴影,低端机可能掉帧,建议移动端降低阴影贴图尺寸或直接关闭阴影。
投中的分数能接到后台吗?
可以。计分是一个自增变量并同步到右上角的 DOM 元素,在自增那一行加上你的上报逻辑即可,比如发一次接口请求或写进本地存储做排行榜。
纸团穿过桶壁掉出去了怎么办?
这是投掷速度过大导致的单帧穿透。可以把重力和松手初速的上限调小,或者提高判定的容差范围。源码里对松手速度已经做了限幅,需要更严格时改那两个夹取范围即可。
这段特效适合放在什么位置
它自带一个小小的叙事和一个可反复玩的动作,适合做办公协作类产品的落地页、邮件营销工具的功能演示、企业年会互动大屏,也能改成“把烦恼揉了扔掉”的情绪化活动页。屏幕纹理绘制、顶点形变揉纸、裁剪面吐纸与投掷判定的完整实现都在源码里,下载后可查看。