尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Browser-based 3D nutrition-training activity: build a plate in three.js, watch calories and macros live, and check it against scenarios. No build step.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A browser-based 3D nutrition-training activity: click foods onto a plate, watch calories and macros update live, pick a scenario such as Type 2 diabetes lunch, and check the plate against its goals.
Live demo · three.js · plain ES modules · no build step · zero dependencies
Hands-on nutrition education often uses a table of food models: learners build a plate, then a facilitator talks through what is on it. When a program moves from in-person instruction to virtual delivery, that exercise needs a browser-native equivalent. This project is a prototype of that exercise, the kind of activity a simulation-based health-worker curriculum might embed in a module. It is a portfolio piece, not a product: the goal was a convincing interactive loop built in an afternoon, with a structure that can grow.
| Scenario | Goals |
|---|---|
| Free build | None; coach notes only |
| Type 2 diabetes lunch | at least 2 vegetables · carbs ≤ 45% of calories · no treats · ≤ 700 kcal |
| Post-workout recovery | protein ≥ 30% of calories · ≤ 800 kcal · at least 1 vegetable |
| MyPlate-style balance | half the items are produce · a grain, a protein and a dairy serving · fat ≤ 35% of calories |
python3 -m http.server 8000
Then open http://localhost:8000. Opening index.html directly as a file will not work: the page uses ES modules and fetch, which browsers block over file://. Any static file server is fine.
node --test
Twelve tests (Node 18+, no packages to install) cover the spec's acceptance cases, the macro arithmetic, and every scenario's goals. They also validate that scenarios.json only references metrics and operators that exist, so a typo in a scenario fails CI instead of failing silently in the browser.
| File | Role |
|---|---|
index.html | Page shell, side panel markup, three.js import map |
style.css | Canvas-plus-panel layout; stacks on narrow screens |
main.js | Scene setup, raycast interaction, animations, panel updates |
rules.js | Pure nutrition logic: totals, macro percentages, coach notes, scenario goals |
foods.json | Food catalog: shape, colour, size, food group, nutrition per serving |
scenarios.json | Scenarios and their goals |
tests/rules.test.js | node --test suite for rules.js and the data files |
PerspectiveCamera with OrbitControls, a hemisphere fill plus a shadow-casting directional light, a wooden table and a white plate. Every food is a three.js primitive with a flat colour; the carrot is a cone on its side, the egg a stretched sphere, the cheese a three-sided cylinder.Raycaster on pointerup. A pointer that moved more than 5 px between down and up is an orbit drag, not a click, so rotating the camera never adds food. Hover is one raycast per animation frame and drives the highlight and tooltip.rules.js has no DOM or three.js imports, so the same functions run in the browser and under node --test. Scenario goals are declarative (metric, op, value) and evaluated generically.main.js under the spec's ~300-line budget. Scenarios pushed it past that, so the nutrition logic moved to rules.js, which also made it unit-testable without a browser.Pushing to main runs the tests and publishes the repository root to GitHub Pages through the workflow in .github/workflows/pages.yml. In the repository settings, set Pages → Source to GitHub Actions once.
MIT. Simplified rules for demonstration; not dietary advice.