{"id":34599131,"url":"https://github.com/flyingrobots/html-to-cloth","last_synced_at":"2026-05-24T13:34:01.453Z","repository":{"id":319085449,"uuid":"1074108675","full_name":"flyingrobots/html-to-cloth","owner":"flyingrobots","description":"Let's turn HTML DOM elements into physics cloth, for fun.","archived":false,"fork":false,"pushed_at":"2025-11-28T07:32:10.000Z","size":1993,"stargazers_count":0,"open_issues_count":17,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-25T23:42:58.388Z","etag":null,"topics":["browser-art","cloth-simulation","delight","experimental","fun","game-engine","html2image","interactive-visualizations","not-supposed-to-do-that","performance-art","physics","skeuomorphism","webgl2"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flyingrobots.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-11T06:47:44.000Z","updated_at":"2025-11-28T07:32:13.000Z","dependencies_parsed_at":"2025-10-18T02:29:25.894Z","dependency_job_id":"fcb4b3b6-6d14-4299-a0f5-8f050c79e97e","html_url":"https://github.com/flyingrobots/html-to-cloth","commit_stats":null,"previous_names":["flyingrobots/cloth-web-demo","flyingrobots/html-to-cloth"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/flyingrobots/html-to-cloth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyingrobots%2Fhtml-to-cloth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyingrobots%2Fhtml-to-cloth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyingrobots%2Fhtml-to-cloth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyingrobots%2Fhtml-to-cloth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flyingrobots","download_url":"https://codeload.github.com/flyingrobots/html-to-cloth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flyingrobots%2Fhtml-to-cloth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33436554,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-24T13:13:05.286Z","status":"ssl_error","status_checked_at":"2026-05-24T13:13:03.728Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser-art","cloth-simulation","delight","experimental","fun","game-engine","html2image","interactive-visualizations","not-supposed-to-do-that","performance-art","physics","skeuomorphism","webgl2"],"created_at":"2025-12-24T12:07:29.158Z","updated_at":"2026-05-24T13:34:01.422Z","avatar_url":"https://github.com/flyingrobots.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HTML-to-cloth\n\n\u003cimg src=\"https://github.com/user-attachments/assets/976ff0de-e55b-46d6-990b-bba48cbe741e\" width=\"480\" align=\"right\" /\u003e\n\nA portfolio playground that hides a WebGL cloth simulation beneath an accessible DOM layout. Clicking any `.cloth-enabled` element swaps it for a textured mesh, lets the fabric react to pointer gusts, and eventually returns the DOM element when the cloth falls off screen. The codebase is deliberately modular so the experiment can be reused for future interactive sites.\n\n## Architecture at a Glance\n\n| Layer | Responsibilities | Source |\n| ----- | ---------------- | ------ |\n| UI / DOM | captures elements, handles pointer input, debug UI | `src/lib/clothSceneController.ts` + React components (Mantine) |\n| Render | applies camera snapshot to DOMToWebGL and renders each frame | `src/engine/render/worldRendererSystem.ts`, `src/lib/domToWebGL.ts` |\n| Camera | spring camera with read-only snapshots | `src/engine/camera/CameraSystem.ts`, `src/engine/camera/CameraSpring.ts` |\n| Simulation | cloth physics, collision clamps, sleep/wake, scheduler | `src/lib/clothPhysics.ts`, `src/lib/simWorld.ts`, `src/lib/collisionSystem.ts` |\n| Engine | fixed-step loop \u0026 system ordering | `src/engine/simulationRunner.ts`, `src/engine/world.ts` |\n| Entity | lightweight ECS tracking cloth body adapters | `src/engine/entity/` |\n\nLong-form docs live in:\n\n- [`docs/architecture.md`](docs/architecture.md) – layer overview, DI strategy, extension tips.\n- [`docs/components.md`](docs/components.md) – Mermaid component diagram.\n- [`docs/data-flow.md`](docs/data-flow.md) – step-by-step activation/update/offscreen flows.\n- Generated API docs (`npm run docs:api`) end up in `docs/api/`.\n\n## Getting Started\n\n```bash\nnpm install\nnpm run dev        # start the Vite dev server\nnpm run build      # type-check + production bundle\nnpm test           # run Vitest suites\nnpm run docs:api   # generate Markdown API reference via TypeDoc\n```\n\nKey entry points:\n\n- `src/App.tsx` – React shell + debug drawer wiring (Mantine components, zero custom CSS).\n- `src/lib/clothSceneController.ts` – DOM orchestration + simulation delegation (rendering handled by a system).\n- `src/engine/render/worldRendererSystem.ts` – applies the camera snapshot and calls DOMToWebGL render.\n- `src/engine/camera/CameraSystem.ts` – spring-based camera that exposes read-only snapshots.\n- `src/engine/simulationRunner.ts` – deterministic fixed-step loop.\n- `src/lib/clothPhysics.ts` – cloth solver plus impulse helpers.\n\n## Testing\n\n- Unit suites cover cloth physics, impulse helpers, simulation scheduler, SimWorld, entity lifecycle, and the simulation runner.\n- Integration suite (`src/lib/__tests__/domIntegration.test.ts`) verifies DOM capture, activation lifecycle, pointer wakeups, offscreen recycling, and debug controls.\n- App UI tests (`src/app/__tests__/debugActions.test.tsx`) assert that the debug palette routes actions into the engine (real-time, substeps, camera zoom, gravity, iterations).\n- Render-while-paused integration (`src/engine/render/__tests__/pausedRenderIntegration.test.ts`) verifies the render system still runs during `engine.frame(dt)` when real-time is disabled.\n\n## UI Library\n\nThe app uses Mantine (no Tailwind, no shadcn/ui). We avoid custom CSS entirely and compose the debug UI purely from Mantine components and props. Global styles come from `@mantine/core/styles.css` imported in `src/main.tsx`.\n\n## Debug Presets\n\nFor quick demos, the debug palette includes presets that apply multiple settings at once:\n\n- Floaty – gravity 6.0, 3 iterations, looser sleep (0.0005, 80f), 1.2× zoom, warm-start 2 passes\n- Crisp – gravity 9.81, 6 iterations, default sleep (0.001, 60f), 1.0× zoom, warm-start 3 passes\n- Heavy – gravity 14.0, 8 iterations, tighter sleep (0.002, 40f), 0.9× zoom, warm-start 1 pass\n- Manual QA scenarios are listed in [`TEST_PLAN.md`](TEST_PLAN.md); progress is tracked in [`PROGRESS_CHECKLIST.md`](PROGRESS_CHECKLIST.md).\n\n## Workflow\n\nWe follow the cycle described in [`AGENTS.md`](AGENTS.md): branch-per-task, write failing specs first, implement, document, log the session, open a PR. Notes and experiments are appended to [`BLOG_NOTES.md`](BLOG_NOTES.md).\n\nDebug actions entry point: create `EngineActions` with `runner`, `world`, `camera`, and `simulation` from the controller. The UI never reaches into simulation internals directly.\n\n## Roadmap\n\n- Camera/render systems that consume simulation snapshots instead of hand-rolling controller logic.\n- Continuous collision for sweeping pointer helpers.\n- Expanded component library (e.g., cloth analytics, audio emitters) via the entity layer.\n- Portable presets for gravity, pinning, and impulse tuning.\n\nContributions, experiments, and wild ideas are welcome—this repository is a sandbox on purpose.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyingrobots%2Fhtml-to-cloth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflyingrobots%2Fhtml-to-cloth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflyingrobots%2Fhtml-to-cloth/lists"}