🔗 开源仓库 :MysticTarot
事情是这样的。
老婆最近迷上了塔罗牌,购物车里存了好几副设计精美的实体牌,价格都在两三百上下。做技术的我,心里先算了一笔账:这些东西买回来很可能热乎几天就收进抽屉,搬家时还得费力打包。可我又不忍心直接浇灭她的热情,于是主动说:"给我两个小时,我送你一个全宇宙独一无二的线上塔罗牌。"
她白了我一眼,但嘴角分明在说:"你倒是弄出来啊。"
于是,一个叫 MysticTarot 的项目诞生了------基于 Nuxt 3、Three.js 和 AI 的在线占卜应用。回头一算,从动手到能玩,差不多真的就是两个小时。


下面就把这个过程完整复盘一下,看看 AI 是怎么帮我在这么短时间里,从想法到部署,做出一个带 3D 翻牌、AI 解读、多语言和响应式适配的暗黑风塔罗应用。
1. 先让 AI 出一份"技术 & UI 方案"
我的第一步很简单:把需求告诉大语言模型。当时用的是 Gemini,因为它对多模态和多轮对话的支持更好。我给它的提示词大概是这样的:
text
我要做一个 Web 端塔罗牌占卜应用,要求:
- 沉浸式体验,3D 翻牌、洗牌动画
- 78 张牌完整数据(正逆位释义)
- 集成 OpenAI 进行 AI 解读
- 暗黑美学,毛玻璃 UI,星空背景
- 多语言支持(首选中英文)
- 响应式,手机端体验也要好
- 纯前端应用,但可能需要后端代理 API Key
请给我一套完整的技术方案,包括推荐的技术栈、核心组件设计,以及大致的 UI 布局。用 Markdown 输出。
Gemini 很快返回了一份要点清晰的方案:
- 框架:Nuxt 3(Vue 3 + TypeScript),利用其服务端 API 路由代理 OpenAI 请求
- 3D 渲染:TresJS(Three.js 的 Vue 3 封装)+ GSAP 做动画
- 样式 :Tailwind CSS,配合
bg-black/80、backdrop-blur实现毛玻璃,加上翡翠绿 (#50C878) 作为主色调 - 状态管理:Pinia,管理抽牌、洗牌、解读状态
- 多语言:@nuxtjs/i18n
- AI 解读:OpenAI SDK,流式 SSE 响应,并设计无 API Key 时的本地回退策略
- 牌面数据:本地 JSON 存储,包含名称、关键词、正逆位描述等
- 目录结构 :
components/下拆出TarotScene.vue、CardDeck.vue等
这份方案直接帮我省掉了大量纠结"选什么技术"的时间。更关键的是,它还给出了 UI 布局的骨架描述:中央是 3D 牌阵舞台,底下是操作区(洗牌、抽牌),右侧滑出解读面板,顶部导航放语言切换和设置。
有了这张蓝图,下一步就是把蓝图交给 AI 转换成代码。
2. 用"AI 编辑器提示词"生成组件
我没有一行行手写代码,而是把 Gemini 的方案和具体需求,压缩成一段段给 AI 编辑器(Cursor / Antigravity 这类)的提示词。这里分享几个关键提示词,你可以直接拿去参考。
提示词 1:初始化项目基底
text
创建一个 Nuxt 3 + TypeScript + Tailwind CSS 项目。
安装以下依赖:@nuxtjs/tailwindcss, @nuxtjs/i18n, pinia, @vueuse/core, tresjs, gsap, openai
配置 tailwind.config.ts 添加自定义颜色:
emerald-glow: '#50C878',背景黑:#0a0a0a, #121212
在 nuxt.config.ts 中注册 tailwindcss 模块和 i18n 模块。
创建 i18n 配置文件,支持 zh-CN 和 en,设置懒加载。
创建基础布局文件 default.vue,包含星空背景(纯 CSS 点阵或 canvas 动画),全屏占满。
请生成所有需要的配置和文件内容。
AI 编辑器执行后,我得到了一个可以直接跑起来的项目框架,甚至已经带上了基础的星空粒子效果(用 CSS box-shadow 做的散点加动画)。
提示词 2:78 张牌的数据结构 & 本地 JSON
这一步我没有让 AI 自己编造牌义,因为我在网上找到了一份开源的中文塔罗解释,是 JSON 格式。我把这份 JSON 内容作为附件丢给 AI,然后说:
text
这是 78 张塔罗牌的详细数据(文件名:tarot.json),包含名称、英文名、正位关键词、逆位关键词、正位描述、逆位描述等字段。
请根据这份数据,在项目 /assets/ 下创建 tarot.json 文件。
然后在 /types/ 下定义 TypeScript 接口 TarotCard。
并在 /utils/ 中编写一个 loadDeck() 函数,用于读取并解析该 JSON。
AI 完美地生成了类型定义和工具函数,并且提醒我把图片文件放到 /public/cards/ 下,命名直接用牌的 id。这样数据层就扎实了。
提示词 3:TresJS 3D 场景 & 洗牌动画
这是最有挑战的部分,但只要提示词把需求拆解得清楚,AI 就能给出可靠的代码:
text
请使用 TresJS(Vue 3 的 Three.js 封装)创建一个塔罗牌 3D 场景组件 TarotDeck3D.vue。
- 场景背景透明,叠加在页面中央。
- 牌面使用 PlaneGeometry,正面贴图从 /public/images/tarot/ 加载,背面使用统一卡背图片。
- 初始状态:78 张牌叠成一摞,略微倾斜,展示厚度感。
- 点击「洗牌」按钮后,触发 GSAP 动画:所有牌迅速展开成扇形,并伴有随机微动。
- 点击某张牌时,该牌旋转 180 度翻面,并高亮。
- 组件通过 defineEmits 向外暴露 'card-selected' 事件,传递牌的 id。
- 务必使用 TresCanvas 和正确的灯光设置,使牌面纹理显示清晰。
这段提示词我给了 Cursor,它生成了约 200 行代码。虽然第一次生成的扇形角度有点生硬,但我补充了一句:"扇形弧度调整到约 160 度,牌间距均匀",它立刻就修正了算法。
这里的核心经验是:把复杂的动画逻辑拆解成明确的小需求,并清楚告诉 AI 你用的库和 API 形态。
3. "多语言"与"智能降级"------花小钱办大事
我老婆是中文用户,可万一外国朋友也想玩呢?这好办。@nuxtjs/i18n 在项目初始化时就配好了,我只要让 AI 把组件里的所有文字都用 $t() 包裹,再生成对应的语言包就行。
提示词示例:
text
请遍历 components/ 和 pages/ 下的所有 .vue 文件,提取出所有用户可见的中文字符串,
生成完整的 zh-CN.json 和 en.json 语言文件,
并把组件内的文字替换为 {{ $t('key') }} 格式。
Key 使用英文命名,例如 "card.shuffle"、"result.loading"。
AI 很快生成了翻译文件,还贴心地为塔罗术语保留了原文,比如 $t('cards.TheFool.name')。
另一个我觉得比较实用的设计是 AI 解读的智能降级。很多同类应用一旦没有 OpenAI Key 就不能用了,而这个应用会在 API 不可用时自动切回本地数据库释义。实现起来其实很巧妙:
- 在
/server/api/analyze.post.ts中,先尝试调用 OpenAI。 - 如果请求失败(401、网络错误等),直接 catch 异常。
- 在 catch 块里,根据抽到的牌 ID 从本地 JSON 中取出正/逆位描述,返回给前端。
这整个过程也是 AI 帮我做的,我只需要说:"如果 OpenAI 请求失败,返回本地解读,状态码还是 200,前端不用管。" 最终用户完全感觉不到切换,体验很顺畅。
4. 移动端适配与翡翠暗黑美学
因为用了 Tailwind,响应式适配在 AI 帮助下特别简单。我只需要在提示词里加一句:
所有布局元素请使用 Mobile First 策略。
在大屏上,解读面板在右侧侧滑;在小屏上,解读面板从底部上滑,高度占屏幕 70%。
AI 自动给面板加上了 fixed bottom-0 md:right-0 md:top-0 md:w-96 这样的类名,并配上过渡动画。
颜色主题方面,暗黑模式已经通过 Tailwind 的 dark: 变体支持了。但我想让整个界面只使用 翡翠绿 作为强调色。于是在提示词里要求:
主题色只使用 emerald-glow 和它的透明度衍生版本。
提供主题切换按钮,通过 Pinia store 管理 isDark 状态,并用 vueuse 的 useDark 同步到 标签上。
最后呈现出来的效果是:深邃的黑色背景上,翡翠绿色的光感从牌背微微透出,毛玻璃面板边缘晕着一层柔光,整界界面确实有几分"赛博占卜"的味道。
5. 最后的样子,和老婆的反馈
差不多两小时后,我把应用部署到了 GitHub Pages,把链接发给老婆。她没说话,默默试了三次占卜,然后抬头说:"牌面比买的还好看诶,那个背景音是什么?"
------没错,我还悄悄加了一个环境音效。用了免费的白噪音音频,让 AI 写了一个 useAmbientSound 的 composable,进入页面时自动淡入播放,可以随时关闭。仪式感就这么拉满了。
现在项目完全开源,你可以直接克隆下来体验或自己改着玩:
- 🔗 开源仓库 :github.com/liuxinyea/m...
- 🌐 在线演示 :liuxinyea.github.io/mystic-taro...
(如果不配置 OpenAI API Key,应用会自动运行在本地解读模式,仍然可以抽牌并看到内置的详细释义。)
6. 被 AI 帮了多少?说点真心话
老实说,如果没有 AI,这两个小时我可能刚搭完 Nuxt 环境,还在跟 TresJS 的类型定义较劲。AI 对我的帮助主要体现在:
- 加速决策:技术选型、组件划分、UI 风格------这些原本要纠结半小时的事,AI 在几十秒内给出了合理建议。
- 减少记忆负担 :不用记
GSAP.to的参数顺序,不用查@nuxtjs/i18n的配置细节,把脑力留给真正需要判断的地方。 - 快速纠错 :有一次 3D 旋转出现奇怪的倾斜,把代码扔给 AI,它一眼看出是
rotation属性的应用顺序问题。
当然,AI 不是魔法。整个过程我仍然要不断调整提示词,检查它生成的代码有没有副作用、是否符合最佳实践。但效率的提升是实实在在的------就像拍电影,我只需要讲清楚分镜头,AI 帮我把画面演出来。
如果你也有一个突然冒出来的想法,不妨试试这种"AI 原生"的开发方式。说不定下一个项目,就诞生在某个赌气的瞬间、一个没清空的购物车,和两个小时的专注里。
如果这篇分享对你有用,欢迎去仓库点个 Star,也欢迎直接在线玩一玩~ 🌟