老婆天天吵吵要买塔罗牌,我直接用 AI 2 小时写了个在线塔罗牌

🔗 开源仓库MysticTarot

🌐 在线预览liuxinyea.github.io/mystic-taro...

事情是这样的。

老婆最近迷上了塔罗牌,购物车里存了好几副设计精美的实体牌,价格都在两三百上下。做技术的我,心里先算了一笔账:这些东西买回来很可能热乎几天就收进抽屉,搬家时还得费力打包。可我又不忍心直接浇灭她的热情,于是主动说:"给我两个小时,我送你一个全宇宙独一无二的线上塔罗牌。"

她白了我一眼,但嘴角分明在说:"你倒是弄出来啊。"

于是,一个叫 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/80backdrop-blur 实现毛玻璃,加上翡翠绿 (#50C878) 作为主色调
  • 状态管理:Pinia,管理抽牌、洗牌、解读状态
  • 多语言:@nuxtjs/i18n
  • AI 解读:OpenAI SDK,流式 SSE 响应,并设计无 API Key 时的本地回退策略
  • 牌面数据:本地 JSON 存储,包含名称、关键词、正逆位描述等
  • 目录结构components/ 下拆出 TarotScene.vueCardDeck.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 不可用时自动切回本地数据库释义。实现起来其实很巧妙:

  1. /server/api/analyze.post.ts 中,先尝试调用 OpenAI。
  2. 如果请求失败(401、网络错误等),直接 catch 异常。
  3. 在 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,进入页面时自动淡入播放,可以随时关闭。仪式感就这么拉满了。

现在项目完全开源,你可以直接克隆下来体验或自己改着玩:

(如果不配置 OpenAI API Key,应用会自动运行在本地解读模式,仍然可以抽牌并看到内置的详细释义。)


6. 被 AI 帮了多少?说点真心话

老实说,如果没有 AI,这两个小时我可能刚搭完 Nuxt 环境,还在跟 TresJS 的类型定义较劲。AI 对我的帮助主要体现在:

  • 加速决策:技术选型、组件划分、UI 风格------这些原本要纠结半小时的事,AI 在几十秒内给出了合理建议。
  • 减少记忆负担 :不用记 GSAP.to 的参数顺序,不用查 @nuxtjs/i18n 的配置细节,把脑力留给真正需要判断的地方。
  • 快速纠错 :有一次 3D 旋转出现奇怪的倾斜,把代码扔给 AI,它一眼看出是 rotation 属性的应用顺序问题。

当然,AI 不是魔法。整个过程我仍然要不断调整提示词,检查它生成的代码有没有副作用、是否符合最佳实践。但效率的提升是实实在在的------就像拍电影,我只需要讲清楚分镜头,AI 帮我把画面演出来。

如果你也有一个突然冒出来的想法,不妨试试这种"AI 原生"的开发方式。说不定下一个项目,就诞生在某个赌气的瞬间、一个没清空的购物车,和两个小时的专注里。


如果这篇分享对你有用,欢迎去仓库点个 Star,也欢迎直接在线玩一玩~ 🌟

相关推荐
代码搬运媛4 小时前
Jest 测试框架详解与实现指南
前端
counterxing5 小时前
Agent 跑起来之后,难的是复用、观测和评测
node.js·agent·ai编程
uccs5 小时前
大模型底层机制与Agent开发
agent·ai编程·claude
counterxing5 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq5 小时前
windows下nginx的安装
linux·服务器·前端
夜雪闻竹6 小时前
vectra 向量索引文件损坏怎么办
ai编程·向量·vectra
ZzT6 小时前
Harness 到底指什么
openai·ai编程·claude
之歆6 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
宅小年6 小时前
AI 创业最危险的地方:太容易做出来
openai·ai编程·claude
发现一只大呆瓜6 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite