上午测试了用 React + SVG + CSS Transform 实现解密游戏。
场景切换
首先,通过 React Router 来切换场景的体验还不错。一个通用的 SceneLayout,允许输入 top/left/right/bottom 的链接,会在场景边缘展示对应的 NavLink 按钮,点了之后就可以切换场景了。这个东西还可以做到从主菜单进入游戏内场景等等,这一部分我很喜欢。
门
然后具体的场景布置,测试了一下「门」,体验也还不错,只要父元素上有 perspective 属性,就可以让子元素在 3D 变换的时候有透视效果。

一个注意事项是,边框这种东西应该加给门的同一级的元素,而不是父元素,不然在门关上的时候会出现重复的边框。
窗——两扇门
然后「窗」其实也是类似,毕竟窗就是两扇相对的门。只不过这个抽象的门可能需要扩展一下,让它更加定制化。
考虑增加:
- 门把手,并且要能处理锁定状态。
- 可选的背景色
- size 定制
- 考虑如何增加更多设计细节,「质感」的东西。
感觉可以设计成 headless 组件,现场组装。
更新
关于门的设计,也不一定像 Shadcn UI 那样用 headless 组件的结构,直接用 props 传递「零件」进去更简单。
然后需要设定的属性可能有:
开关状态,门的方向(可以直接用带符号的角度),宽高,开门的方向,铰链的位置。
再更新:
大致做了一个版本的可以配置的 Door 组件。支持 children / foreground / background / handler 分别是门的本体,前景(适合做门框,确切来说是外开门的边框。当然更高级的门框也可以做,让门留出边距就可以),背景(门打开看到的画面),把手。
取巧的地方:
发现旋转 div 会导致 div 下面的 svg 的描边有锯齿,但是直接旋转 svg 不会。所以 children / foreground / background / handler 都是直接传的 svg 子元素(比如 g 和 rect),实际旋转操作的是 Door 内创建的 svg 元素,这样的另一个好处是可以共用 width / height。

然后迭代
然后这个东西就被放弃了,虽然门窗真的可以翻转到任意角度,但是很难想象一扇门是一个平面,没有突出的把手跟随旋转。而,如果要拼凑出复杂的零件,问题就变得特别复杂了。
我又跑回去看锈湖的设计,锈湖这个窗户(以及很多情况下的柜门),没有中间帧,可以说是完全「翻」过去的。点了之后会直接绕一侧轴水平翻转,变成镜像状态。只在变化末尾有一个水平方向的弹性效果。

于是我借鉴来,做了一个叫做 FlipDoor 之类的东西。

最后,还有个演示视频:
可以在 PROJECT ??? 中体验这个设计,动画的部分使用了 motion .