尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗เว็บสุ่มเมนูอาหารในโรงอาหารจุฬาฯ แบบ เปิดซองการ์ด TCG — เลือกโรงอาหาร ตอบคำถามสั้นๆ แล้วฉีกซองลุ้นการ์ดเมนู 3 ใบ เลือกใบที่จะไปกินจริง 1 ใบเก็บเข้า collection และแชร์ให้เพื่อนดูได้
Side project / prototype — ไม่มี backend ไม่มี login ข้อมูลทั้งหมดอยู่ใน frontend และเก็บ collection ไว้ในเครื่องผู้ใช้ (localStorage)
persist → localStoragebun install # หรือ npm install
bun dev # หรือ npm run dev
| คำสั่ง | ทำอะไร |
|---|---|
dev | รัน dev server |
build | build production |
start | รัน production build |
lint | ESLint |
/ เลือกโรงอาหาร
/[canteen] เลือกประเภทอาหาร (จานหลัก / ของหวาน 🔒 / เครื่องดื่ม 🔒)
/[canteen]/quiz คำถาม mock
/[canteen]/open เปิดซอง → เลือก 1 ใบ → เก็บเข้า collection
/collection การ์ดที่เก็บไว้ทั้งหมด + ปุ่มแชร์
/card/[menuId] หน้าการ์ดใบเดียว (ลิงก์แชร์ มี OG image)
/c?d=<encoded> collection ของเพื่อนแบบอ่านอย่างเดียว
ทุก route prerender แบบ static ผ่าน generateStaticParams
src/
├── app/
│ ├── [canteen]/open/ หน้าเปิดซอง
│ │ ├── director.ts ลำดับ animation ทั้งหมด (state: ready → tearing → reveal → choose → saved)
│ │ ├── fx.ts GSAP plugins + เอฟเฟกต์ (burst, sparkles, shake)
│ │ └── sfx.ts เสียงสังเคราะห์ด้วย Web Audio API
│ ├── collection/ c/ card/[menuId]/
├── components/ FoodCard, CardBack, ShareButtons, PacksLeft ฯลฯ
├── config/flow.ts ชื่อแอป ชื่อซอง ประเภทอาหาร และคำถาม quiz
├── data/ canteens.json, shops.json, menus.json
└── lib/
├── pack.ts logic สุ่มการ์ดในซอง
├── meal.ts แบ่งมื้อ + จำนวนซองต่อมื้อ + countdown
├── share.ts encode/decode ลิงก์ collection + แชร์รูป/ลิงก์
├── store.ts zustand store (collection, ซองที่ใช้, คำตอบ quiz, ปิดเสียง)
└── data.ts helper อ่านข้อมูล + ตัวเลือก SHARED_POOL
scripts/convert-cards.mjs แปลงรูปการ์ดจากดีไซเนอร์เป็น webp
| ค่า | ไฟล์ | ค่าเริ่มต้น |
|---|---|---|
จำนวนการ์ดต่อซอง CARDS_PER_PACK | src/lib/pack.ts | 3 |
โอกาสได้ Rare ต่อช่อง RARE_CHANCE | src/lib/pack.ts | 0.2 |
ซองต่อมื้อ PACKS_PER_MEAL | src/lib/meal.ts | 3 |
เวลาเริ่มแต่ละมื้อ SLOTS | src/lib/meal.ts | 06:00 / 10:30 / 15:00 / 21:00 |
สุ่มจากกองรวมทุกโรงอาหาร SHARED_POOL | src/lib/data.ts | true |
| ชื่อแอป / ชื่อซอง / คำถาม quiz | src/config/flow.ts | — |
ตอนนี้มีการ์ดแค่ 8 ใบ จึงตั้ง
SHARED_POOL = trueให้ทุกโรงอาหารสุ่มจากกองเดียวกัน เมื่อมีเมนูครบแต่ละโรงอาหารแล้วให้เปลี่ยนเป็นfalse
วางไฟล์รูปการ์ดจากดีไซเนอร์ (1.png, 2.png, … ขนาด 1500×2100) ไว้ในโฟลเดอร์หนึ่ง แล้วรัน
node scripts/convert-cards.mjs <โฟลเดอร์รูป>
สคริปต์จะย่อเป็น 750×1050 แล้วบันทึกเป็น public/cards/001.webp, 002.webp, …
เพิ่มเมนูใน src/data/menus.json ให้ id ตรงกับชื่อไฟล์การ์ด
{
"id": "009",
"shopId": "arts-4",
"canteenId": "arts",
"name": "ชื่อเมนู",
"type": "main",
"price": 50,
"rarity": "common",
"image": "/cards/009.webp",
"spicy": 0,
"tags": ["rice"]
}
spicy (0–3) และ tags ยังไม่ได้ใช้ แต่เตรียมไว้สำหรับกรองเมนูจาก quiz
ถ้าเป็นร้านใหม่ ให้เพิ่มใน src/data/shops.json ด้วย
price, spicy, tags)SHARED_POOLรูปโรงอาหารจาก Wikimedia Commons (CC BY-SA) — ดูรายชื่อผู้ถ่ายได้ในช่อง credit ของ src/data/canteens.json