Compare commits
19 Commits
5ddb5b8618
...
0f9a918873
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f9a918873 | |||
| f360b1438c | |||
| 52a50ff7ae | |||
| e9df2b5254 | |||
| 56cb4011f6 | |||
| 1cde453293 | |||
| cc8cd25668 | |||
| a86970622c | |||
| dcef19f4d7 | |||
| 98849cc0a0 | |||
| bc0db8864c | |||
| 0397b444bf | |||
| d9742132c0 | |||
| bfa16a1db3 | |||
| ecb7fc26fb | |||
| 36a9fbbb09 | |||
| df80db8a89 | |||
| 73034ebf67 | |||
| 5d3475ebf0 |
@ -1,60 +1,66 @@
|
||||
# Task: [Feature Name]
|
||||
# Task: Parent-Child Hierarchy
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
The objective was to create a simple 3D scene with two objects in a parent-child hierarchy, then verify that transformations applied to the parent (such as position and scale) are correctly inherited by the child.
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented by creating sunMesh and attaching an earthOrbit group to it (`sunMesh.add(earthOrbit)`), then adding earthMesh to that group. Parent transforms propagate correctly to child.
|
||||
- Key concepts: Scene graph hierarchy, `THREE.Group` as orbit pivot, local vs world transforms, animation loop for orbit/spin.
|
||||
- Complexity: Easy
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented by nesting Earth inside a `<group ref={orbitRef}>` inside the Sun `<mesh>`, making Earth a child in the same scene graph hierarchy.
|
||||
- What R3F abstracted: Declarative JSX scene creation, automatic render lifecycle integration with React, and frame updates via `useFrame` instead of manual renderer/loop setup.
|
||||
- Complexity: Easy
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented by putting the Earth mesh inside the Sun mesh (parent-child). Changing Sun position/scale also affects Earth as expected (Earth follows position and scale inheritance). However, when Earth position is changed directly, Earth shape appears to distort/stretch as it moves farther from Sun but when POI controls are added and we move around a bit we can notice that the earth is correct in size and shape it is just appering distorted/stretched from certain positions/angels.
|
||||
- Builder steps: Create Sun mesh -> add Earth mesh as child of Sun -> test parent transform inheritance by changing Sun position/scale -> test child local transform by changing Earth position.
|
||||
- Complexity: Easy
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
- Possible in all 3? Yes
|
||||
- Main differences:
|
||||
- Vanilla gives explicit low-level control;
|
||||
- R3F gives cleaner declarative hierarchy;
|
||||
- Thob gives fastest visual setup but less predictable child transform behavior in this case.
|
||||
- Animation was not possible in Thob but was possible in vanilla and r3f.
|
||||
- Where Thob is better: Quick setup and visual parenting without writing code.
|
||||
- Where Thob is weaker: Child transform behavior is less transparent when editing child position under a transformed parent.
|
||||
- What feels awkward or unclear: Local vs inherited transforms are not obvious in the editor, and distortion behavior on child position change is unexpected.
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
- [x] Editor UX limitation
|
||||
- [x] Runtime limitation
|
||||
- [ ] Schema / data model limitation
|
||||
- [x] Component limitation
|
||||
- [ ] Event system limitation
|
||||
- [ ] Asset pipeline limitation
|
||||
- [ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
- Is there a workaround?
|
||||
- NO
|
||||
- No, I tried a lot of different things, like grouping and wraping in flex inside the parent mesh and different ways to place the components.
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
- What should improve in Thob?
|
||||
- Make transform inheritance behavior explicit and stable for nested meshes, especially when parent scale is applied and child position is edited.
|
||||
- It is:
|
||||
- editor
|
||||
- component
|
||||
- runtime
|
||||
- UX
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
Easy
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
- Yes. Parent-child transform consistency is a core 3D workflow; reliable nested transforms reduce confusion, improve trust in the builder, and make more advanced scenes practical without code-level debugging.
|
||||
87
Week-1/Task-1/builder/BuilderNotes.md
Normal file
87
Week-1/Task-1/builder/BuilderNotes.md
Normal file
@ -0,0 +1,87 @@
|
||||
# Builder Notes (Thob) — Task 1: Parent-Child Hierarchy
|
||||
|
||||
## Thob Observations from Task Notes
|
||||
|
||||
- **Possible:** Yes
|
||||
- **Implementation used:** Earth mesh was placed inside Sun mesh to create a parent-child relationship.
|
||||
- **What worked as expected:**
|
||||
- Changing Sun position moved Earth with it.
|
||||
- Changing Sun scale also scaled Earth (inherited transform behavior).
|
||||
- **Unexpected behavior observed:**
|
||||
- Changing Earth position directly caused visual distortion/stretch-like behavior as Earth moved farther from Sun.
|
||||
- **Builder flow used:**
|
||||
1. Create Sun mesh.
|
||||
2. Add Earth mesh as child of Sun.
|
||||
3. Change Sun position/scale to verify inheritance.
|
||||
4. Change Earth local position to test child transform.
|
||||
- **Complexity:** Easy
|
||||
- **Main limitation signals:** Editor UX + Component + Runtime concerns.
|
||||
- **Workaround status:** No reliable workaround found after trying multiple groups/flex layouts and different placement approaches.
|
||||
|
||||
## Console Warnings/Errors Seen (Deduplicated) and Probable Meaning
|
||||
|
||||
### warn: `Permissions-Policy header unrecognized feature ('browsing-topics')`
|
||||
- **Type:** Browser/header compatibility warning.
|
||||
- **Probable meaning:** A server response includes a `Permissions-Policy` directive with `browsing-topics`, but the browser/runtime does not recognize it.
|
||||
- **Impact:** Usually low for editor functionality; mostly noise unless policy enforcement is required.
|
||||
|
||||
### warn: `Component changing from uncontrolled to controlled`
|
||||
- **Type:** React state-management warning.
|
||||
- **Probable meaning:** UI components are initialized without a stable value and later receive a controlled value (or vice versa).
|
||||
- **Impact:** Can cause flaky UI behavior (selection glitches, inconsistent panel state), especially in property editors.
|
||||
|
||||
### warn: `GetBindingData... method already registered`
|
||||
- **Type:** Internal registration/duplicate listener warning.
|
||||
- **Probable meaning:** Binding handlers are being registered repeatedly (possibly on rerender/remount) without proper cleanup/de-duplication.
|
||||
- **Impact:** High log noise, possible duplicated updates, degraded performance over time.
|
||||
|
||||
### warn: `resetPOI/update-static-component-prop method already registered`
|
||||
- **Type:** Duplicate method registration warning.
|
||||
- **Probable meaning:** Same command/event pipeline is attached multiple times.
|
||||
- **Impact:** Multiple executions of one action, state drift, and performance overhead.
|
||||
|
||||
### error: `THREE.GLTFLoader invalid plugin (missing name)`
|
||||
- **Type:** Asset loader/plugin configuration error.
|
||||
- **Probable meaning:** A GLTF loader plugin object is passed without required `name` metadata or wrong plugin shape.
|
||||
- **Impact:** Model import pipeline may partially fail or skip plugin behavior.
|
||||
|
||||
### warn: `THREE.MaterialLoader undefined texture (null)`
|
||||
- **Type:** Asset/material reference warning.
|
||||
- **Probable meaning:** Material expects a texture slot but received `null`/missing reference.
|
||||
- **Impact:** Material may render incorrectly; not always fatal.
|
||||
|
||||
### error: `Cannot read properties of null (reading 'contentWindow')`
|
||||
- **Type:** Runtime exception.
|
||||
- **Probable meaning:** Code tries to post a message to an iframe/window that is not mounted or already destroyed.
|
||||
- **Impact:** Can break sync/preview communication and interrupt some editor actions.
|
||||
|
||||
### error: `THREE.WebGLRenderer context lost`
|
||||
- **Type:** Graphics runtime warning/error.
|
||||
- **Probable meaning:** WebGL context got dropped (GPU reset, heavy resource pressure, canvas recreation, or browser throttling).
|
||||
- **Impact:** Preview can freeze/black out until context is restored.
|
||||
|
||||
### error: `Failed to load resource (404)`
|
||||
- **Type:** Network/resource error.
|
||||
- **Probable meaning:** A referenced asset/component/resource ID does not exist or URL/path is stale.
|
||||
- **Impact:** Missing assets/components in scene and follow-up loader warnings.
|
||||
|
||||
### warn: `Icon component has been deprecated`
|
||||
- **Type:** Deprecation warning.
|
||||
- **Probable meaning:** Code path still uses an older icon API.
|
||||
- **Impact:** Non-blocking now, but future break risk if API is removed.
|
||||
|
||||
### warn: `ReconnectingWebSocket reconnecting/syncing events`
|
||||
- **Type:** Collaboration/sync transport logs.
|
||||
- **Probable meaning:** WebSocket connection dropped and resumed normal sync handshake.
|
||||
- **Impact:** Usually informational; frequent reconnects may indicate unstable connection/session.
|
||||
|
||||
### error: `R3F: Div is not part of the THREE namespace`
|
||||
- **Type:** Critical scene composition/runtime error.
|
||||
- **Probable meaning:** A DOM element (`Div`) is being rendered inside R3F 3D canvas tree where only Three.js objects (or properly extended objects) are valid.
|
||||
- **Impact:** Can break render subtree and cause scene/editor preview failures.
|
||||
|
||||
## Overall Read
|
||||
|
||||
- The hierarchy feature itself works for basic parent transform inheritance.
|
||||
- The major risk signals are repeated duplicate registrations, controlled/uncontrolled UI transitions, and mixed runtime/render errors.
|
||||
- The distortion observed during child position edits aligns with the broader instability indicated by runtime/component warnings.
|
||||
@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>solar-system</title>
|
||||
<title>Task1 R3f - Solar System</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Solar System</title>
|
||||
<title>Task1 vanilla - Solar System</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
|
||||
@ -1,60 +1,83 @@
|
||||
# Task: [Feature Name]
|
||||
# Task: Parent-Child-Grandchild Hierarchy (Sun -> Earth -> Moon)
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
The objective was to create a 3-level hierarchy where the Sun is parent, Earth is child, and Moon is grandchild, then validate orbit and self-rotation behavior with clear local vs inherited transforms.
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented as `solarSystem -> sun -> earthOrbit -> earth -> moonOrbit -> moon`. Earth orbits Sun by rotating `earthOrbit`; Moon orbits Earth by rotating `moonOrbit`; Earth self-rotates on local Y.
|
||||
- Key concepts: Scene graph hierarchy, transform inheritance, local transform pivots with `Object3D`, frame-time based animation.
|
||||
- Complexity: Easy
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented the same hierarchy with nested JSX nodes and `group` refs in `useFrame` for orbit updates.
|
||||
- What R3F abstracted: Declarative tree for parent/child relationships, lifecycle/render loop integration with `useFrame`, less boilerplate for setup.
|
||||
- Complexity: Easy
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Partial (based on Task 1 behavior)
|
||||
- Notes: Parent-child worked in Task 1, but child transform behavior became unstable when editing child position under transformed parent. Task 2 extends this to a deeper hierarchy (parent-child-grandchild), so predictability risk increases.
|
||||
- Builder steps:
|
||||
1. Create Sun mesh.
|
||||
2. Create Earth as child of Sun.
|
||||
3. Create Moon as child of Earth (grandchild of Sun).
|
||||
4. Test parent transform inheritance (Sun move/scale).
|
||||
5. Test child and grandchild local transforms independently.
|
||||
- Complexity: Medium
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
- Possible in all 3? Partial
|
||||
- Main differences:
|
||||
- Vanilla gives explicit and predictable control over every transform.
|
||||
- R3F keeps the same predictability with easier hierarchy expression.
|
||||
- Thob is fast for setup, but deeper nested transform behavior may be harder to trust when local edits are involved.
|
||||
- Where Thob is better: Fast visual authoring and parenting without code.
|
||||
- Where Thob is weaker: Transform debugging and local-vs-inherited clarity in deeper hierarchies.
|
||||
- What feels awkward or unclear: It is not always obvious which transform comes from parent inheritance vs local overrides.
|
||||
|
||||
## Evaluation Questions
|
||||
- Are transforms predictable?
|
||||
- Vanilla: Yes.
|
||||
- R3F: Yes.
|
||||
- Thob: Partially; basic inheritance works, but nested local edits can feel unstable.
|
||||
- Is it easy to reason about local vs inherited motion?
|
||||
- Vanilla: Yes, because hierarchy and pivot objects are explicit in code.
|
||||
- R3F: Yes, because nested JSX mirrors scene graph structure clearly.
|
||||
- Thob: Not always; editor feedback for transform source is limited.
|
||||
- Does the builder make hierarchy understandable?
|
||||
- Partially. Parenting can be created quickly, but understanding and debugging multi-level transform behavior is less transparent than code-based setups.
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
- [x] Editor UX limitation
|
||||
- [x] Runtime limitation
|
||||
- [ ] Schema / data model limitation
|
||||
- [x] Component limitation
|
||||
- [ ] Event system limitation
|
||||
- [ ] Asset pipeline limitation
|
||||
- [ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
- Is there a workaround?
|
||||
- No
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
- What should improve in Thob?
|
||||
- Add clearer transform inspector support for inherited vs local values in nested hierarchies.
|
||||
- Provide stable multi-level pivot behavior (parent-child-grandchild) when position/scale are edited.
|
||||
- Add hierarchy visualization and world/local gizmo clarity.
|
||||
- Is it:
|
||||
- editor
|
||||
- runtime
|
||||
- component
|
||||
- UX
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
Medium
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
- Yes. Parent-child-grandchild transform reliability is fundamental for non-trivial 3D scenes and directly affects trust, speed, and correctness for builders making interactive experiences.
|
||||
141
Week-1/Task-2/builder/BuilderNotes.md
Normal file
141
Week-1/Task-2/builder/BuilderNotes.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Builder Notes (Thob) — Task 2: Parent-Child-Grandchild Hierarchy
|
||||
|
||||
## Scope
|
||||
|
||||
- This task extends Task 1 from a 2-level hierarchy (parent-child) to a 3-level hierarchy:
|
||||
- Sun (parent)
|
||||
- Earth (child)
|
||||
- Moon (grandchild)
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
- Moving/scaling Sun should affect Earth and Moon.
|
||||
- Moving/scaling Earth should affect Moon but not Sun.
|
||||
- Moving/scaling Moon should affect only Moon.
|
||||
- Local orbit controls should remain stable when parent transforms change.
|
||||
|
||||
## Evaluation
|
||||
|
||||
### Are transforms predictable?
|
||||
|
||||
- **Observation:** Partially predictable.
|
||||
- **What seems to work:** Basic parent inheritance generally works.
|
||||
- **Risk area:** Multi-level nested local edits can become hard to trust, especially when parent scale and child position both change.
|
||||
|
||||
### Is it easy to reason about local vs inherited motion?
|
||||
|
||||
- **Observation:** Not always.
|
||||
- **Reason:** In the visual editor, it is not always explicit whether a value is local to the selected object or the result of parent inheritance.
|
||||
- **Impact:** Harder debugging when Moon behavior is unexpectedly affected by Sun/Earth changes.
|
||||
|
||||
### Does the builder make hierarchy understandable?
|
||||
|
||||
- **Observation:** Partially.
|
||||
- **Positive:** Creating parent-child links is quick and intuitive.
|
||||
- **Gap:** Understanding final motion in deeper hierarchies needs better transform visibility and clearer hierarchy debugging tools.
|
||||
|
||||
## Builder Flow Used (Task 2)
|
||||
|
||||
1. Create Sun mesh as root object.
|
||||
2. Add Earth as child of Sun.
|
||||
3. Add Moon as child of Earth.
|
||||
4. Validate transform inheritance at each depth level.
|
||||
5. Test local edits on Earth and Moon independently.
|
||||
|
||||
## Main Limitation Signals
|
||||
|
||||
- Editor UX: Limited visibility into local vs world/inherited transform values.
|
||||
- Runtime/Component: Nested transform interactions can be difficult to reason about as hierarchy depth increases.
|
||||
|
||||
## Workaround Attempt
|
||||
|
||||
- Keep transforms simple and incremental.
|
||||
- Test one hierarchy level at a time before combining all levels.
|
||||
- Avoid aggressive parent scaling before child/grandchild positioning is finalized.
|
||||
|
||||
## Suggested Product Improvements
|
||||
|
||||
1. Show explicit local and world transform values side-by-side.
|
||||
2. Add hierarchy debugging mode to highlight inheritance path (Sun -> Earth -> Moon).
|
||||
3. Add transform source indicators (local override vs inherited contribution).
|
||||
4. Improve nested pivot stability when parent scale and child position are both edited.
|
||||
|
||||
## Console Logs from Builder Webpage
|
||||
## Console Warnings/Errors Seen (Deduplicated) and Probable Meaning
|
||||
|
||||
### warn: `No HydrateFallback element provided to render during initial hydration`
|
||||
- **Type:** SSR/CSR hydration warning.
|
||||
- **Probable meaning:** UI expects a fallback during hydration but none is configured.
|
||||
- **Impact:** Can cause temporary blank/flash states and inconsistent first paint in editor panels.
|
||||
|
||||
### warn: `Component is changing from uncontrolled to controlled` (Tabs / Popover / RadioGroup / undefined)
|
||||
- **Type:** React state-management warning.
|
||||
- **Probable meaning:** Components mount with no stable value (`undefined`) and later receive a controlled value.
|
||||
- **Impact:** Property panel controls may behave inconsistently (selection reset, unexpected toggles, unstable form state).
|
||||
|
||||
### warn: `Permissions-Policy header: Unrecognized feature 'browsing-topics'`
|
||||
- **Type:** Browser/header compatibility warning.
|
||||
- **Probable meaning:** Server sends a policy directive not recognized by the current browser.
|
||||
- **Impact:** Usually low for scene behavior; mostly noise unless strict policy handling is required.
|
||||
|
||||
### warn: `GetBindingData... method already registered` (many IDs)
|
||||
- **Type:** Duplicate registration warning.
|
||||
- **Probable meaning:** Binding handlers are registered repeatedly across rerenders/reconnects without cleanup.
|
||||
- **Impact:** High log noise, potential duplicate updates, performance degradation, and confusing transform propagation behavior.
|
||||
|
||||
### warn: `resetPOI method already registered`
|
||||
- **Type:** Duplicate command registration warning.
|
||||
- **Probable meaning:** POI reset handler attached multiple times.
|
||||
- **Impact:** Same action can fire multiple times; camera/selection state may drift.
|
||||
|
||||
### warn: `update-static-component-prop method already registered`
|
||||
- **Type:** Duplicate command registration warning.
|
||||
- **Probable meaning:** Static prop update pipeline is attached repeatedly.
|
||||
- **Impact:** Duplicate property writes and unstable editor state during transform edits.
|
||||
|
||||
### error: `THREE.GLTFLoader: Invalid plugin found: missing name`
|
||||
- **Type:** Asset loader/plugin error.
|
||||
- **Probable meaning:** A GLTF loader plugin is passed with invalid shape or missing `name` field.
|
||||
- **Impact:** Model import/plugin extension paths may fail partially and emit follow-up rendering issues.
|
||||
|
||||
### warn: `THREE.MaterialLoader: Undefined texture null`
|
||||
- **Type:** Material/asset reference warning.
|
||||
- **Probable meaning:** Material expects a texture reference but receives `null`.
|
||||
- **Impact:** Missing/incorrect material rendering; usually non-fatal but degrades visual fidelity.
|
||||
|
||||
### error: `Cannot read properties of null (reading 'contentWindow')`
|
||||
- **Type:** Runtime exception.
|
||||
- **Probable meaning:** Code attempts to post/sync to an iframe/window that is not mounted or already disposed.
|
||||
- **Impact:** Sync/preview communication can break, causing editor-preview mismatch.
|
||||
|
||||
### info/warn: `ReconnectingWebSocket reconnecting/open/syncing/...`
|
||||
- **Type:** Collaboration transport reconnection events.
|
||||
- **Probable meaning:** Socket drops and reconnects, then replays sync steps.
|
||||
- **Impact:** Usually informational, but frequent reconnects correlate with duplicate registration warnings and state churn.
|
||||
|
||||
### warn: `Icon component has been deprecated`
|
||||
- **Type:** Deprecation warning.
|
||||
- **Probable meaning:** Legacy icon API still used in parts of the editor UI.
|
||||
- **Impact:** Low immediate risk; medium future break risk on upgrades.
|
||||
|
||||
### error: `THREE.WebGLRenderer: Context Lost`
|
||||
- **Type:** Graphics runtime error.
|
||||
- **Probable meaning:** WebGL context dropped (resource pressure, repeated remounts, GPU/browser reset).
|
||||
- **Impact:** Canvas can freeze/blank; transform testing becomes unreliable until context restoration.
|
||||
|
||||
### error: `Failed to load resource: 404`
|
||||
- **Type:** Network/resource error.
|
||||
- **Probable meaning:** Requested project/resource ID or asset URL is missing/stale.
|
||||
- **Impact:** Missing resources can trigger secondary loader/material warnings and broken scene state.
|
||||
|
||||
### error: `R3F: Div is not part of the THREE namespace`
|
||||
- **Type:** Critical scene composition/runtime error.
|
||||
- **Probable meaning:** A DOM element (`Div`) was rendered inside the R3F scene tree without proper bridging/extension.
|
||||
- **Impact:** Can fail rendering subtree, break scene updates, and invalidate hierarchy behavior testing.
|
||||
|
||||
## Overall Read
|
||||
|
||||
- Console output indicates significant editor/runtime instability beyond normal warning noise.
|
||||
- Duplicate handler registration and uncontrolled/controlled state transitions are the dominant recurring signals.
|
||||
- Rendering pipeline errors (`R3F Div`, `Context Lost`, loader/material issues) likely amplify unpredictability in parent-child-grandchild transform behavior.
|
||||
- This log profile supports the Task 2 conclusion: hierarchy setup is possible, but transform predictability and local-vs-inherited reasoning are only partially reliable in current builder conditions.
|
||||
24
Week-1/Task-2/r3f/solar-system/.gitignore
vendored
Normal file
24
Week-1/Task-2/r3f/solar-system/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
16
Week-1/Task-2/r3f/solar-system/README.md
Normal file
16
Week-1/Task-2/r3f/solar-system/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
29
Week-1/Task-2/r3f/solar-system/eslint.config.js
Normal file
29
Week-1/Task-2/r3f/solar-system/eslint.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs.flat.recommended,
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
||||
},
|
||||
},
|
||||
])
|
||||
13
Week-1/Task-2/r3f/solar-system/index.html
Normal file
13
Week-1/Task-2/r3f/solar-system/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task2 R3f - Solar System</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
2815
Week-1/Task-2/r3f/solar-system/package-lock.json
generated
Normal file
2815
Week-1/Task-2/r3f/solar-system/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
Week-1/Task-2/r3f/solar-system/package.json
Normal file
29
Week-1/Task-2/r3f/solar-system/package.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "solar-system",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.4.0",
|
||||
"vite": "^8.0.0"
|
||||
}
|
||||
}
|
||||
52
Week-1/Task-2/r3f/solar-system/src/App.jsx
Normal file
52
Week-1/Task-2/r3f/solar-system/src/App.jsx
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
import { Canvas, useFrame } from '@react-three/fiber'
|
||||
import { useRef } from 'react'
|
||||
|
||||
function SolarSystem() {
|
||||
const earthOrbitRef = useRef()
|
||||
const moonOrbitRef = useRef()
|
||||
const earthRef = useRef()
|
||||
|
||||
useFrame((_, delta) => {
|
||||
earthOrbitRef.current.rotation.y += delta * 0.9
|
||||
moonOrbitRef.current.rotation.y += delta * 2.2
|
||||
earthRef.current.rotation.y += delta * 2.1
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<ambientLight intensity={0.2} />
|
||||
<pointLight position={[0, 0, 0]} intensity={120} />
|
||||
|
||||
<mesh scale={[2.4, 2.4, 2.4]}>
|
||||
<sphereGeometry args={[1, 32, 32]} />
|
||||
<meshStandardMaterial color="#ffcc55" emissive="#ffaa00" emissiveIntensity={1.2} />
|
||||
|
||||
<group ref={earthOrbitRef}>
|
||||
<mesh ref={earthRef} position={[8, 0, 0]} scale={[0.65, 0.65, 0.65]}>
|
||||
<sphereGeometry args={[1, 32, 32]} />
|
||||
<meshStandardMaterial color="#2a66ff" roughness={0.9} metalness={0.05} />
|
||||
|
||||
<group ref={moonOrbitRef}>
|
||||
<mesh position={[2.2, 0, 0]} scale={[0.28, 0.28, 0.28]}>
|
||||
<sphereGeometry args={[1, 32, 32]} />
|
||||
<meshStandardMaterial color="#bbbbbb" roughness={1} metalness={0} />
|
||||
</mesh>
|
||||
</group>
|
||||
</mesh>
|
||||
</group>
|
||||
</mesh>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Canvas camera={{ fov: 60, near: 0.1, far: 100, position: [0, 0, 22] }}>
|
||||
<color attach="background" args={['#000000']} />
|
||||
<SolarSystem />
|
||||
</Canvas>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
15
Week-1/Task-2/r3f/solar-system/src/index.css
Normal file
15
Week-1/Task-2/r3f/solar-system/src/index.css
Normal file
@ -0,0 +1,15 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
10
Week-1/Task-2/r3f/solar-system/src/main.jsx
Normal file
10
Week-1/Task-2/r3f/solar-system/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
7
Week-1/Task-2/r3f/solar-system/vite.config.js
Normal file
7
Week-1/Task-2/r3f/solar-system/vite.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
28
Week-1/Task-2/vanilla/index.html
Normal file
28
Week-1/Task-2/vanilla/index.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Task2 vanilla - Solar System</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
background: white;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body> <script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
93
Week-1/Task-2/vanilla/main.js
Normal file
93
Week-1/Task-2/vanilla/main.js
Normal file
@ -0,0 +1,93 @@
|
||||
import * as THREE from 'three';
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x000000);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(60, 2, 0.1, 100);
|
||||
camera.position.set(0, 0, 22);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.18);
|
||||
scene.add(ambientLight);
|
||||
|
||||
const sunlight = new THREE.PointLight(0xffffff, 350, 300);
|
||||
scene.add(sunlight);
|
||||
|
||||
const solarSystem = new THREE.Object3D();
|
||||
scene.add(solarSystem);
|
||||
|
||||
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
|
||||
|
||||
const sunMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xffcc55,
|
||||
emissive: 0xffaa00,
|
||||
emissiveIntensity: 1.2,
|
||||
});
|
||||
const sun = new THREE.Mesh(sphereGeometry, sunMaterial);
|
||||
sun.scale.set(2.4, 2.4, 2.4);
|
||||
solarSystem.add(sun);
|
||||
|
||||
const earthOrbit = new THREE.Object3D();
|
||||
earthOrbit.position.set(0, 0, 0);
|
||||
sun.add(earthOrbit);
|
||||
|
||||
const earthMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0x2a66ff,
|
||||
roughness: 0.9,
|
||||
metalness: 0.05,
|
||||
});
|
||||
const earth = new THREE.Mesh(sphereGeometry, earthMaterial);
|
||||
earth.scale.set(0.65, 0.65, 0.65);
|
||||
earth.position.x = 8;
|
||||
earthOrbit.add(earth);
|
||||
|
||||
const moonOrbit = new THREE.Object3D();
|
||||
moonOrbit.position.set(0, 0, 0);
|
||||
earth.add(moonOrbit);
|
||||
|
||||
const moonMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xbbbbbb,
|
||||
roughness: 1,
|
||||
metalness: 0,
|
||||
});
|
||||
const moon = new THREE.Mesh(sphereGeometry, moonMaterial);
|
||||
moon.scale.set(0.28, 0.28, 0.28);
|
||||
moon.position.x = 2.2;
|
||||
moonOrbit.add(moon);
|
||||
|
||||
const EARTH_SPIN_SPEED = 2.1;
|
||||
|
||||
let previousTime = 0;
|
||||
|
||||
function resizeRendererToDisplaySize() {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
const needResize = renderer.domElement.width !== width || renderer.domElement.height !== height;
|
||||
if (needResize) {
|
||||
renderer.setSize(width, height, false);
|
||||
camera.aspect = width / height;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
function render(time) {
|
||||
const seconds = time * 0.001;
|
||||
const delta = seconds - previousTime;
|
||||
previousTime = seconds;
|
||||
|
||||
resizeRendererToDisplaySize();
|
||||
|
||||
sun.rotation.y = seconds * 0.3;
|
||||
earthOrbit.rotation.y = seconds * 0.9;
|
||||
earth.rotation.y += delta * EARTH_SPIN_SPEED;
|
||||
moonOrbit.rotation.y = seconds * 2.2;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
||||
requestAnimationFrame(render);
|
||||
@ -4,9 +4,15 @@
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your Three.js dev script here'",
|
||||
"build": "echo 'Add your Three.js build script here'",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
},
|
||||
"dependencies": {
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
@ -1,60 +1,121 @@
|
||||
# Task: [Feature Name]
|
||||
# Task: Duplicate Object / Duplicate Group
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
Duplicate an object and, if possible, duplicate a grouped structure.
|
||||
|
||||
## Test File Split
|
||||
- Vanilla object duplication test: `main.js`
|
||||
- Vanilla group duplication test: `group.js`
|
||||
- R3F object duplication test: `src/App.jsx`
|
||||
- R3F group duplication test: `src/Group.jsx`
|
||||
- Run object test: default route
|
||||
- Command (Vanilla object): `npm run dev:object` or `yarn dev:object`
|
||||
- Command (Vanilla group): `npm run dev:group` or `yarn dev:group`
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes:
|
||||
- Object duplication is in `main.js` using mesh clone.
|
||||
- Group duplication is in `group.js` using `THREE.Group()` and group clone.
|
||||
- Transforms preserved: Yes, duplicate keeps copied transform values and can be moved independently after duplication.
|
||||
- Structure preserved: Yes, child hierarchy is preserved when duplicating a group.
|
||||
- Linked or independent: Mostly independent transforms, but geometry and material are shared by default unless explicitly cloned.
|
||||
- UX clean: Yes for developers, but requires code understanding.
|
||||
- Key concepts:
|
||||
- Object3D clone behavior
|
||||
- Shared vs cloned geometry and material
|
||||
- Complexity: Easy
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes:
|
||||
- Object duplication is in `src/App.jsx` using repeated meshes with shared geometry/material.
|
||||
- Group duplication is in `src/Group.jsx` by rendering the grouped component twice.
|
||||
- Transforms preserved: Yes, each instance has its own position, rotation, and scale.
|
||||
- Structure preserved: Yes, component tree/group structure is preserved.
|
||||
- Linked or independent: Instance transforms are independent; geometry/material may be shared or isolated depending on how props/instances are created.
|
||||
- UX clean: Yes, declarative and easier to scale.
|
||||
- What R3F abstracted:
|
||||
- Imperative clone calls become declarative repeated components/instances.
|
||||
- Complexity: Easy
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes:
|
||||
- There is a shortcut to duplicate objects.
|
||||
- Observed behavior: duplicate creates a completely different object that cannot be linked to the original, unlike vanilla and R3F patterns where sharing/linking behavior can be controlled.
|
||||
- Duplicate group behavior: Same as single object duplication, a complete copy is made with no linking.
|
||||
- Transforms preserved: Yes.
|
||||
- Structure preserved: Yes, as copy- paste duplication.
|
||||
- Linked or independent: Independent only, with no linking behavior available.
|
||||
- UX clean: Mixed. Shortcut is quick, but behavior is confusing because linked duplication is not possible.
|
||||
- Builder steps:
|
||||
- Create an object
|
||||
- Use duplicate shortcut
|
||||
- Duplicate a grouped structure and verify it is a full independent copy
|
||||
- Complexity: Medium
|
||||
|
||||
## What to Observe
|
||||
- Are transforms preserved?
|
||||
- Vanilla: Yes
|
||||
- R3F: Yes
|
||||
- Thob: Yes
|
||||
- Does duplication preserve structure?
|
||||
- Vanilla: Yes
|
||||
- R3F: Yes
|
||||
- Thob: Yes, as full copy- paste duplication
|
||||
- Does the duplicate remain linked or independent?
|
||||
- Vanilla: Transform- independent, data can be shared by default unless cloned
|
||||
- R3F: Transform- independent, sharing depends on implementation
|
||||
- Thob: Independent only, no linking behavior
|
||||
- Is the UX clean?
|
||||
- Vanilla: Technical but predictable
|
||||
- R3F: Clean and scalable
|
||||
- Thob: Fast shortcut, but ambiguous result for duplication semantics
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
- Possible in all 3? Yes
|
||||
- Main differences:
|
||||
- Vanilla and R3F give clear control over sharing vs independence.
|
||||
- Thob duplicate shortcut creates separate objects and does not support linked behavior.
|
||||
- Where Thob is better:
|
||||
- Fast editor action for simple duplication
|
||||
- Where Thob is weaker:
|
||||
- No linked duplication model
|
||||
- No linked group duplication model
|
||||
- What feels awkward or unclear:
|
||||
- No option to keep duplicates linked for synchronized edits
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
- [x] Editor UX limitation
|
||||
- [ ] Runtime limitation
|
||||
- [x] Schema / data model limitation
|
||||
- [ ] Component limitation
|
||||
- [ ] Event system limitation
|
||||
- [ ] Asset pipeline limitation
|
||||
- [ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
- Is there a workaround?
|
||||
- Yes
|
||||
- If yes, what is it?
|
||||
- Use reusable components/prefabs and instantiate multiple independent copies.
|
||||
- If linked behavior is required, use explicit shared data/component references where supported.
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
- What should improve in Thob?
|
||||
- Add explicit duplicate modes: independent duplicate and linked duplicate.
|
||||
- Add reliable deep group duplication with clear hierarchy preview.
|
||||
- it Is:
|
||||
- editor
|
||||
- schema/data
|
||||
- UX
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
- Medium
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
- High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
Yes. Thob should support both independent and linked duplication because currently duplication works as copy-paste only, which limits synchronized workflows.
|
||||
104
Week-1/Task-3/builder/BuilderNotes.md
Normal file
104
Week-1/Task-3/builder/BuilderNotes.md
Normal file
@ -0,0 +1,104 @@
|
||||
# Builder Notes (Thob) — Task 3: Duplicate Object / Duplicate Group
|
||||
|
||||
## Thob Observations from Task Notes
|
||||
|
||||
- **Possible:** Yes
|
||||
- **Implementation used:** Duplicate shortcut for both single object and grouped structure.
|
||||
- **What worked as expected:**
|
||||
- Duplicating a single object creates a visible copy.
|
||||
- Duplicating a group also creates a full copied hierarchy.
|
||||
- Transforms are preserved at duplication time.
|
||||
- **Key behavior observed:**
|
||||
- Both object duplicate and group duplicate behave as copy-paste.
|
||||
- Duplicates are independent; no linking/reference relationship is maintained with source.
|
||||
- **UX quality:**
|
||||
- Shortcut-based duplication is fast.
|
||||
- Missing duplicate mode (linked vs independent) makes behavior limiting for synchronized edits.
|
||||
- **Builder flow used:**
|
||||
1. Create base object.
|
||||
2. Duplicate object using editor shortcut.
|
||||
3. Create grouped hierarchy.
|
||||
4. Duplicate the group.
|
||||
5. Verify copied transforms/structure and check whether source and duplicate remain linked.
|
||||
- **Complexity:** Medium
|
||||
- **Main limitation signals:** Editor UX + Schema/Data model.
|
||||
- **Workaround status:** Use independent duplicate copies only; no linked duplication path found.
|
||||
|
||||
## Console Warnings/Errors Seen (Deduplicated) and Probable Meaning
|
||||
|
||||
### warn: `Permissions-Policy header unrecognized feature ('browsing-topics')`
|
||||
- **Type:** Browser/header compatibility warning.
|
||||
- **Probable meaning:** Server sends a policy directive unsupported by current browser runtime.
|
||||
- **Impact:** Usually low for duplication behavior; mostly environmental noise.
|
||||
|
||||
### warn: `GetBindingData... method already registered` (many IDs)
|
||||
- **Type:** Duplicate registration warning.
|
||||
- **Probable meaning:** Binding handlers are re-registered on rerender/reconnect without cleanup.
|
||||
- **Impact:** High log noise, duplicate callback execution risk, and possible unstable editor reactions.
|
||||
|
||||
### warn: `resetPOI method already registered`
|
||||
- **Type:** Duplicate command registration.
|
||||
- **Probable meaning:** Camera/POI command pipeline attached multiple times.
|
||||
- **Impact:** One user action may run multiple times, causing state drift.
|
||||
|
||||
### warn: `update-static-component-prop method already registered`
|
||||
- **Type:** Duplicate update-pipeline registration.
|
||||
- **Probable meaning:** Static prop update handlers are mounted repeatedly.
|
||||
- **Impact:** Duplicate writes and inconsistent property panel behavior.
|
||||
|
||||
### warn: `Component changing from uncontrolled to controlled` (Popover / RadioGroup / undefined)
|
||||
- **Type:** React form-state warning.
|
||||
- **Probable meaning:** Controls mount with unstable/undefined value and later switch to controlled mode.
|
||||
- **Impact:** UI flicker, unstable inspector controls, and harder-to-trust edit state.
|
||||
|
||||
### error: `THREE.GLTFLoader: Invalid plugin found: missing name`
|
||||
- **Type:** Asset loader/plugin configuration error.
|
||||
- **Probable meaning:** GLTF plugin object shape is invalid or missing required metadata.
|
||||
- **Impact:** Import pipeline may partially fail and generate secondary rendering issues.
|
||||
|
||||
### warn: `THREE.MaterialLoader: Undefined texture null`
|
||||
- **Type:** Asset/material reference warning.
|
||||
- **Probable meaning:** Material references missing texture slot(s).
|
||||
- **Impact:** Incorrect materials or degraded visual fidelity; usually non-fatal.
|
||||
|
||||
### info/warn: `ReconnectingWebSocket reconnecting/open/syncing/...`
|
||||
- **Type:** Transport/sync lifecycle logs.
|
||||
- **Probable meaning:** Session reconnect and state sync handshakes are occurring.
|
||||
- **Impact:** Usually informational, but repeated reconnects can amplify duplicate registration side effects.
|
||||
|
||||
### error: `Cannot read properties of null (reading 'contentWindow')`
|
||||
- **Type:** Runtime exception.
|
||||
- **Probable meaning:** Message post attempted against iframe/window not mounted or already disposed.
|
||||
- **Impact:** Preview communication can fail and editor state can desynchronize.
|
||||
|
||||
### warn: `Icon component has been deprecated`
|
||||
- **Type:** Deprecation warning.
|
||||
- **Probable meaning:** Legacy UI API still in use.
|
||||
- **Impact:** Low immediate risk; medium future maintenance risk.
|
||||
|
||||
### error: `R3F: Div is not part of the THREE namespace`
|
||||
- **Type:** Critical render-tree composition error.
|
||||
- **Probable meaning:** DOM node rendered in R3F scene tree without proper bridge/extension.
|
||||
- **Impact:** Scene subtree can fail rendering, affecting reliability of duplication validation.
|
||||
|
||||
### error: `THREE.WebGLRenderer: Context Lost`
|
||||
- **Type:** Graphics runtime error.
|
||||
- **Probable meaning:** WebGL context dropped (resource pressure, repeated remounts, browser/GPU reset).
|
||||
- **Impact:** Canvas interruptions and unreliable editor preview behavior.
|
||||
|
||||
### error: `Failed to load resource: 404`
|
||||
- **Type:** Network/resource error.
|
||||
- **Probable meaning:** Asset/resource path missing or stale.
|
||||
- **Impact:** Missing resources can cascade into loader/material warnings.
|
||||
|
||||
### warn/error: `Konva has no node with type ambientLight/meshStandardMaterial/boxGeometry/mesh` and layer width/height warnings
|
||||
- **Type:** Renderer mismatch/runtime warnings.
|
||||
- **Probable meaning:** Non-Konva scene nodes are being interpreted in a Konva path; invalid layer size updates applied.
|
||||
- **Impact:** Rendering fallback behavior and layout/render correctness risk.
|
||||
|
||||
## Overall Read
|
||||
|
||||
- Task objective is functionally reachable in builder: object and group duplication both produce full copies.
|
||||
- Behavior is strictly independent copy-paste; no linked duplicate mode is currently available.
|
||||
- Transform and structure preservation are acceptable at duplicate time, but advanced synchronized editing workflows are not supported.
|
||||
- Console profile indicates substantial runtime/editor noise (duplicate registrations, state-control warnings, renderer/path mismatches), which can reduce confidence in complex scene editing even though basic duplication works.
|
||||
15
Week-1/Task-3/r3f/index.html
Normal file
15
Week-1/Task-3/r3f/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 3 R3F - Cube Clone</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -2,11 +2,23 @@
|
||||
"name": "week-1-task-3-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your React Three Fiber dev script here'",
|
||||
"build": "echo 'Add your React Three Fiber build script here'",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Lint not configured yet'",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist build .next"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
16
Week-1/Task-3/r3f/src/App.jsx
Normal file
16
Week-1/Task-3/r3f/src/App.jsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Canvas } from '@react-three/fiber'
|
||||
import CubePair from './CubeDuplicate'
|
||||
import GroupedStructure from './Group'
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Canvas camera={{ fov: 60, near: 0.1, far: 100, position: [0, 0, 6] }}>
|
||||
<color attach="background" args={['#101418']} />
|
||||
<ambientLight intensity={0.6} />
|
||||
<directionalLight intensity={1.1} position={[4, 6, 5]} />
|
||||
{/* <CubePair /> */}
|
||||
<GroupedStructure position={[-1.4, 0, 0]} direction={1}/>
|
||||
<GroupedStructure position={[ 1.4, 0, 0]} direction={1}/>
|
||||
</Canvas>
|
||||
)
|
||||
}
|
||||
47
Week-1/Task-3/r3f/src/CubeDuplicate.jsx
Normal file
47
Week-1/Task-3/r3f/src/CubeDuplicate.jsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
import * as THREE from 'three'
|
||||
|
||||
function CubePair() {
|
||||
const leftCubeRef = useRef()
|
||||
const rightCubeRef = useRef()
|
||||
|
||||
const sharedGeometry = useMemo(() => new THREE.BoxGeometry(1, 1, 1), [])
|
||||
const sharedMaterial = useMemo(() => new THREE.MeshStandardMaterial({ color: '#5bc0eb' }), [])
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
sharedGeometry.dispose()
|
||||
sharedMaterial.dispose()
|
||||
}
|
||||
}, [sharedGeometry, sharedMaterial])
|
||||
|
||||
useFrame((state) => {
|
||||
const seconds = state.clock.elapsedTime
|
||||
|
||||
if (leftCubeRef.current) {
|
||||
leftCubeRef.current.rotation.x = seconds
|
||||
leftCubeRef.current.rotation.y = seconds
|
||||
}
|
||||
|
||||
if (rightCubeRef.current) {
|
||||
rightCubeRef.current.rotation.x = seconds
|
||||
rightCubeRef.current.rotation.y = -seconds
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<mesh ref={leftCubeRef} position={[-1.2, 0, 0]} geometry={sharedGeometry} material={sharedMaterial} />
|
||||
|
||||
<mesh
|
||||
ref={rightCubeRef}
|
||||
position={[1.2, 0, 0]}
|
||||
geometry={sharedGeometry}
|
||||
material={sharedMaterial}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default CubePair
|
||||
44
Week-1/Task-3/r3f/src/Group.jsx
Normal file
44
Week-1/Task-3/r3f/src/Group.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { Canvas, useFrame } from '@react-three/fiber'
|
||||
import { useRef } from 'react'
|
||||
|
||||
function GroupedStructure({ position = [0, 0, 0], direction = 1 }) {
|
||||
const groupRef = useRef()
|
||||
|
||||
useFrame((state) => {
|
||||
const seconds = state.clock.elapsedTime
|
||||
|
||||
if (!groupRef.current) return
|
||||
|
||||
groupRef.current.rotation.y = direction * seconds * 0.7
|
||||
groupRef.current.rotation.x = Math.sin(seconds * 1.1) * 0.2
|
||||
})
|
||||
|
||||
return (
|
||||
<group ref={groupRef} position={position}>
|
||||
<mesh position={[0, -0.2, 0]}>
|
||||
<boxGeometry args={[0.7, 1.6, 0.7]} />
|
||||
<meshStandardMaterial color="#f6bd60" />
|
||||
</mesh>
|
||||
|
||||
<mesh position={[0, 0.95, 0]}>
|
||||
<sphereGeometry args={[0.4, 24, 24]} />
|
||||
<meshStandardMaterial color="#84a59d" />
|
||||
</mesh>
|
||||
</group>
|
||||
)
|
||||
}
|
||||
|
||||
export default GroupedStructure
|
||||
|
||||
// export default function GroupApp() {
|
||||
// return (
|
||||
// <Canvas camera={{ fov: 60, near: 0.1, far: 100, position: [0, 1.2, 8] }}>
|
||||
// <color attach="background" args={['#101418']} />
|
||||
// <ambientLight intensity={0.65} />
|
||||
// <directionalLight intensity={1.1} position={[4, 6, 5]} />
|
||||
|
||||
// <GroupedStructure position={[-1.4, 0, 0]} direction={1} />
|
||||
// <GroupedStructure position={[1.4, 0, 0]} direction={-1} />
|
||||
// </Canvas>
|
||||
// )
|
||||
// }
|
||||
18
Week-1/Task-3/r3f/src/index.css
Normal file
18
Week-1/Task-3/r3f/src/index.css
Normal file
@ -0,0 +1,18 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
background: #101418;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
10
Week-1/Task-3/r3f/src/main.jsx
Normal file
10
Week-1/Task-3/r3f/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
6
Week-1/Task-3/r3f/vite.config.js
Normal file
6
Week-1/Task-3/r3f/vite.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
68
Week-1/Task-3/vanilla/group.js
Normal file
68
Week-1/Task-3/vanilla/group.js
Normal file
@ -0,0 +1,68 @@
|
||||
import * as THREE from "three"
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true })
|
||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
|
||||
document.body.appendChild(renderer.domElement)
|
||||
|
||||
const scene = new THREE.Scene()
|
||||
scene.background = new THREE.Color(0x101418)
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(60, 2, 0.1, 100)
|
||||
camera.position.set(0, 1.2, 8)
|
||||
|
||||
scene.add(new THREE.AmbientLight(0xffffff, 0.65))
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1.1)
|
||||
light.position.set(4, 6, 5)
|
||||
scene.add(light)
|
||||
|
||||
const pillarGeometry = new THREE.BoxGeometry(0.7, 1.6, 0.7)
|
||||
const pillarMaterial = new THREE.MeshStandardMaterial({ color: 0xf6bd60 })
|
||||
const capGeometry = new THREE.SphereGeometry(0.4, 24, 24)
|
||||
const capMaterial = new THREE.MeshStandardMaterial({ color: 0x84a59d })
|
||||
|
||||
const groupedStructure = new THREE.Group()
|
||||
|
||||
const pillar = new THREE.Mesh(pillarGeometry, pillarMaterial)
|
||||
pillar.position.y = -0.2
|
||||
groupedStructure.add(pillar)
|
||||
|
||||
const cap = new THREE.Mesh(capGeometry, capMaterial)
|
||||
cap.position.y = 0.95
|
||||
groupedStructure.add(cap)
|
||||
|
||||
groupedStructure.position.set(-1.4, 0, 0)
|
||||
scene.add(groupedStructure)
|
||||
|
||||
const groupedStructureClone = groupedStructure.clone()
|
||||
groupedStructureClone.position.set(1.4, 0, 0)
|
||||
scene.add(groupedStructureClone)
|
||||
|
||||
function resizeRendererToDisplaySize() {
|
||||
const width = window.innerWidth
|
||||
const height = window.innerHeight
|
||||
const needResize = renderer.domElement.width !== width || renderer.domElement.height !== height
|
||||
|
||||
if (needResize) {
|
||||
renderer.setSize(width, height, false)
|
||||
camera.aspect = width / height
|
||||
camera.updateProjectionMatrix()
|
||||
}
|
||||
}
|
||||
|
||||
function animate(time) {
|
||||
const seconds = time * 0.001
|
||||
|
||||
resizeRendererToDisplaySize()
|
||||
|
||||
groupedStructure.rotation.y = seconds * 0.7
|
||||
groupedStructure.rotation.x = Math.sin(seconds * 1.1) * 0.2
|
||||
|
||||
groupedStructureClone.rotation.y = -seconds * 0.7
|
||||
groupedStructureClone.rotation.x = Math.sin(seconds * 1.1) * 0.2
|
||||
|
||||
renderer.render(scene, camera)
|
||||
requestAnimationFrame(animate)
|
||||
}
|
||||
|
||||
requestAnimationFrame(animate)
|
||||
38
Week-1/Task-3/vanilla/index.html
Normal file
38
Week-1/Task-3/vanilla/index.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 3 Vanilla - Duplication Tests</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #101418;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="module">
|
||||
const mode = new URLSearchParams(window.location.search).get('test')
|
||||
|
||||
if (mode === 'group') {
|
||||
import('./group.js')
|
||||
} else {
|
||||
import('./main.js')
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
56
Week-1/Task-3/vanilla/main.js
Normal file
56
Week-1/Task-3/vanilla/main.js
Normal file
@ -0,0 +1,56 @@
|
||||
import * as THREE from "three"
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0x101418);
|
||||
|
||||
const camera = new THREE.PerspectiveCamera(60, 2, 0.1, 100);
|
||||
camera.position.set(0, 0, 6);
|
||||
|
||||
scene.add(new THREE.AmbientLight(0xffffff, 0.6));
|
||||
|
||||
const light = new THREE.DirectionalLight(0xffffff, 1.1);
|
||||
light.position.set(4, 6, 5);
|
||||
scene.add(light);
|
||||
|
||||
const geometry = new THREE.BoxGeometry(1, 1, 1);
|
||||
const material = new THREE.MeshStandardMaterial({ color: 0x5bc0eb });
|
||||
|
||||
const cube = new THREE.Mesh(geometry, material);
|
||||
cube.position.x = -1.2;
|
||||
scene.add(cube);
|
||||
|
||||
const cubeClone = cube.clone();
|
||||
cubeClone.position.x = 1.2;
|
||||
scene.add(cubeClone);
|
||||
|
||||
function resizeRendererToDisplaySize() {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
const needResize = renderer.domElement.width !== width || renderer.domElement.height !== height;
|
||||
|
||||
if (needResize) {
|
||||
renderer.setSize(width, height, false);
|
||||
camera.aspect = width / height;
|
||||
camera.updateProjectionMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
function animate(time) {
|
||||
const seconds = time * 0.001;
|
||||
|
||||
resizeRendererToDisplaySize();
|
||||
|
||||
cube.rotation.x = seconds;
|
||||
cube.rotation.y = seconds;
|
||||
|
||||
cubeClone.rotation.x = seconds;
|
||||
cubeClone.rotation.y = -seconds;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
requestAnimationFrame(animate);
|
||||
@ -4,8 +4,10 @@
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your Three.js dev script here'",
|
||||
"build": "echo 'Add your Three.js build script here'",
|
||||
"dev": "vite",
|
||||
"dev:object": "vite --open '/'",
|
||||
"dev:group": "vite --open '/?test=group'",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
}
|
||||
|
||||
@ -1,60 +1,70 @@
|
||||
# Task: [Feature Name]
|
||||
# Task: Basic Rotation / Motion
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
Create simple motion on an object (cube), such as constant rotation, and compare implementation across Vanilla three.js, R3F, and thob page builder.
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented a simple cube and animated it in the render loop using `renderer.setAnimationLoop(animate)`. Rotation is updated every frame on X and Y axes.
|
||||
- Key concepts: Render loop, frame-time based motion, direct `mesh.rotation` updates.
|
||||
- Complexity: Easy
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Yes
|
||||
- Notes: Implemented the same rotating cube using `useFrame`, with per-frame rotation updates matching the Vanilla behavior.
|
||||
- What R3F abstracted: Scene/render setup and loop integration are simplified with `Canvas` and `useFrame`, reducing boilerplate.
|
||||
- Complexity: Easy
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
- Possible: Partial
|
||||
- Notes: Basic motion can be added through built-in presets, but custom animation logic cannot be authored.
|
||||
- Custom animation is not possible; only the pre-provided animation can be applied.
|
||||
- Builder steps:
|
||||
- Add cube/object in scene.
|
||||
- Select available animation preset from builder controls.
|
||||
- Adjust preset options (like speed).
|
||||
- Complexity: Easy
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
- Possible in all 3? Partial
|
||||
- Main differences:
|
||||
- Vanilla and R3F support fully custom per-frame animation logic.
|
||||
- Thob supports only preset animation options.
|
||||
- Where Thob is better: Fast setup for non-technical users with ready-made motion presets.
|
||||
- Where Thob is weaker: No custom animation authoring for specific motion behavior.
|
||||
- What feels awkward or unclear: Limited control when required motion does not match a preset.
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
- [x] Editor UX limitation
|
||||
- [x] Runtime limitation
|
||||
- [ ] Schema / data model limitation
|
||||
- [x] Component limitation
|
||||
- [ ] Event system limitation
|
||||
- [ ] Asset pipeline limitation
|
||||
- [ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
- Is there a workaround?
|
||||
- Partial
|
||||
- If yes, what is it?
|
||||
- Use the closest pre-provided animation preset and tune available settings.
|
||||
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
- What should improve in Thob?
|
||||
- Allow combining preset animation with user-defined motion parameters.
|
||||
- it is:
|
||||
- editor
|
||||
- runtime
|
||||
- component
|
||||
- UX
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
- Hard
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
- High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
- Yes. Motion is core to interactive 3D scenes, and lack of custom animation blocks many use cases beyond simple showcase interactions.
|
||||
73
Week-1/Task-4/builder/BuilderNotes.md
Normal file
73
Week-1/Task-4/builder/BuilderNotes.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Builder Notes (Thob) — Task 4: Basic Rotation / Motion
|
||||
|
||||
## Thob Observations from Task Notes
|
||||
|
||||
- **Possible:** Partial
|
||||
- **Implementation used:** Applied available built-in animation presets on a cube/object inside thob builder.
|
||||
- **What worked as expected:**
|
||||
- Preset animation can be applied quickly.
|
||||
- Basic motion effects are visible without writing code.
|
||||
- **Main limitation observed:**
|
||||
- Custom animation is not possible; only pre-provided animation can be applied.
|
||||
- Exact motion parity with Vanilla/R3F frame-loop logic is not achievable from the builder controls.
|
||||
- **Builder flow used:**
|
||||
1. Create/Add cube object in scene.
|
||||
2. Open animation controls.
|
||||
3. Apply available preset animation.
|
||||
4. Tune exposed preset options (for example speed/intensity where available).
|
||||
- **Complexity:** Easy for preset motion, hard for custom motion requirements.
|
||||
- **Main limitation signals:** Editor UX + Runtime + Component concerns.
|
||||
- **Workaround status:** Partial workaround only (use nearest preset); no true custom per-frame animation authoring.
|
||||
|
||||
## Console Warnings/Errors Seen (Deduplicated) and Probable Meaning
|
||||
|
||||
### warn: `Permissions-Policy header unrecognized feature ('browsing-topics')`
|
||||
- **Type:** Browser/header compatibility warning.
|
||||
- **Probable meaning:** Response header includes a policy directive not recognized by the current browser engine.
|
||||
- **Impact:** Usually low for scene editing itself; mostly platform/header noise.
|
||||
|
||||
### error: `GET https://builder.thob.studio/builder/<id> 404 (Not Found)`
|
||||
- **Type:** Network/resource error.
|
||||
- **Probable meaning:** Builder page/resource ID is stale, deleted, or inaccessible for current session.
|
||||
- **Impact:** High for workflow continuity; can block loading expected builder state.
|
||||
|
||||
### warn: `Unchecked runtime.lastError: The message port closed before a response was received`
|
||||
- **Type:** Browser extension/runtime messaging warning.
|
||||
- **Probable meaning:** A background messaging channel closed before callback response (often extension-related).
|
||||
- **Impact:** Usually low for core scene logic; can add debugging noise.
|
||||
|
||||
### warn: `No HydrateFallback element provided to render during initial hydration`
|
||||
- **Type:** Hydration/lifecycle warning.
|
||||
- **Probable meaning:** Initial hydration path expected a fallback UI element but none was configured.
|
||||
- **Impact:** Can produce unstable initial editor/preview rendering behavior.
|
||||
|
||||
### warn: `... changing from uncontrolled to controlled` and `RadioGroup is changing from uncontrolled to controlled`
|
||||
- **Type:** React state-management warning.
|
||||
- **Probable meaning:** Form/editor controls switch value ownership mode across renders.
|
||||
- **Impact:** Property panel behavior may become inconsistent or glitchy.
|
||||
|
||||
### warn: `GetBindingData<id> method already registered` (repeated)
|
||||
- **Type:** Duplicate registration warning.
|
||||
- **Probable meaning:** Binding method handlers are attached multiple times during rerender/remount cycles.
|
||||
- **Impact:** High log noise, risk of duplicated side effects, and potential performance degradation.
|
||||
|
||||
### warn: `resetPOI method already registered`
|
||||
- **Type:** Duplicate command registration warning.
|
||||
- **Probable meaning:** Command/event handler is registered more than once without cleanup.
|
||||
- **Impact:** Risk of repeated command execution and state drift.
|
||||
|
||||
### warn: `camera-controls: verticalDragToForward was removed...`
|
||||
- **Type:** API deprecation/removed option warning.
|
||||
- **Probable meaning:** Legacy camera-controls prop is still being used by some path in the runtime/editor.
|
||||
- **Impact:** Non-fatal now, but indicates outdated control configuration and future fragility.
|
||||
|
||||
### error: `THREE.GLTFLoader: Invalid plugin found: missing name`
|
||||
- **Type:** Asset loader/plugin configuration error.
|
||||
- **Probable meaning:** GLTF loader plugin object does not satisfy required shape/metadata.
|
||||
- **Impact:** Asset loading behavior may be incomplete or fail for some models.
|
||||
|
||||
## Overall Read
|
||||
|
||||
- For Task 4, thob supports only preset motion and does not support custom animation logic, which is the core functional gap compared with Vanilla and R3F.
|
||||
- Console output shows repeated registration and controlled/uncontrolled warnings, which aligns with editor/runtime stability concerns when iterating quickly in builder.
|
||||
- The 404 page load and loader/control warnings suggest platform-level reliability and compatibility issues that can interfere with smooth motion-authoring workflows.
|
||||
15
Week-1/Task-4/r3f/index.html
Normal file
15
Week-1/Task-4/r3f/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 4 R3F - Motion/Animation</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -2,11 +2,23 @@
|
||||
"name": "week-1-task-4-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your React Three Fiber dev script here'",
|
||||
"build": "echo 'Add your React Three Fiber build script here'",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Lint not configured yet'",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist build .next"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
30
Week-1/Task-4/r3f/src/App.jsx
Normal file
30
Week-1/Task-4/r3f/src/App.jsx
Normal file
@ -0,0 +1,30 @@
|
||||
import { Canvas, useFrame } from '@react-three/fiber'
|
||||
import { useRef } from 'react'
|
||||
|
||||
function RotatingCube() {
|
||||
const cubeRef = useRef()
|
||||
|
||||
useFrame((state) => {
|
||||
const seconds = state.clock.elapsedTime
|
||||
|
||||
if (!cubeRef.current) return
|
||||
|
||||
cubeRef.current.rotation.x = seconds / 2
|
||||
cubeRef.current.rotation.y = seconds
|
||||
})
|
||||
|
||||
return (
|
||||
<mesh ref={cubeRef}>
|
||||
<boxGeometry args={[1, 1, 1]} />
|
||||
<meshBasicMaterial color={0x00ff00} />
|
||||
</mesh>
|
||||
)
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<Canvas camera={{ fov: 75, near: 0.1, far: 1000, position: [0, 0, 5] }}>
|
||||
<RotatingCube />
|
||||
</Canvas>
|
||||
)
|
||||
}
|
||||
8
Week-1/Task-4/r3f/src/index.css
Normal file
8
Week-1/Task-4/r3f/src/index.css
Normal file
@ -0,0 +1,8 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background-color: black;
|
||||
}
|
||||
10
Week-1/Task-4/r3f/src/main.jsx
Normal file
10
Week-1/Task-4/r3f/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
6
Week-1/Task-4/r3f/vite.config.js
Normal file
6
Week-1/Task-4/r3f/vite.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
18
Week-1/Task-4/vanilla/index.html
Normal file
18
Week-1/Task-4/vanilla/index.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Task4 vanilla - Motion/Animation</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
25
Week-1/Task-4/vanilla/main.js
Normal file
25
Week-1/Task-4/vanilla/main.js
Normal file
@ -0,0 +1,25 @@
|
||||
import * as THREE from 'three';
|
||||
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||
|
||||
const renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setAnimationLoop(animate);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
const geometry = new THREE.BoxGeometry(1, 1, 1);
|
||||
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
|
||||
const cube = new THREE.Mesh(geometry, material);
|
||||
scene.add(cube);
|
||||
|
||||
camera.position.z = 5;
|
||||
|
||||
function animate(time) {
|
||||
|
||||
cube.rotation.x = time / 2000;
|
||||
cube.rotation.y = time / 1000;
|
||||
|
||||
renderer.render(scene, camera);
|
||||
|
||||
}
|
||||
@ -4,9 +4,15 @@
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your Three.js dev script here'",
|
||||
"build": "echo 'Add your Three.js build script here'",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
},
|
||||
"dependencies": {
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
@ -1,26 +1,30 @@
|
||||
# Ansh — Week 1 Summary
|
||||
|
||||
## Tasks Completed
|
||||
-Task 1:
|
||||
-Task 2:
|
||||
-Task 3:
|
||||
-Task 4:
|
||||
- Task 1: Built and compared a parent-child hierarchy (Sun -> Earth) in Vanilla, R3F, and Thob. Confirmed that basic parent transform inheritance works in all three, while Thob showed visual instability when editing child local position under transformed parent setups.
|
||||
- Task 2: Built and compared a 3-level hierarchy (Sun -> Earth -> Moon). Vanilla and R3F stayed predictable for local vs inherited transforms. Thob was partially successful, but deeper nesting made transform behavior harder to reason about and trust.
|
||||
- Task 3: Tested duplicate object and duplicate group behavior. All three supported duplication and preserved structure/transforms. Thob duplication was fast but always independent copy-paste, with no linked duplication mode.
|
||||
- Task 4: Tested basic rotation/motion. Vanilla and R3F supported full custom per-frame animation. Thob supported only preset animations, so motion was possible but not truly customizable.
|
||||
|
||||
## What Thob Supports Well
|
||||
-1.
|
||||
-2.
|
||||
-3.
|
||||
- 1. Very fast visual setup for basic scenes and hierarchy creation without code.
|
||||
- 2. Quick duplicate workflow for both single objects and grouped structures.
|
||||
- 3. Easy entry-level motion using built-in presets for non-technical users.
|
||||
|
||||
## What Feels Weak / Awkward
|
||||
-1.
|
||||
-2.
|
||||
-3.
|
||||
- 1. Local vs inherited transform behavior is not transparent enough in nested hierarchies, making debugging difficult.
|
||||
- 2. No linked duplication option (only independent copies), which limits synchronized editing workflows.
|
||||
- 3. Motion tooling is preset-only, so custom animation logic is not possible for use cases beyond simple demos.
|
||||
|
||||
## Most Product-Relevant Discovery
|
||||
-
|
||||
- Builder speed is valuable, but trust depends on transform predictability and controllability. As soon as hierarchy depth increases or motion needs become custom, reliability and clarity matter more than fast setup.
|
||||
|
||||
## Best Improvement Recommendation
|
||||
-
|
||||
- Prioritize transform reliability and visibility first: add a clear local/world transform inspector, inheritance path visibility for nested objects, and stable parent-child-grandchild behavior when editing position and scale. This would remove the biggest source of confusion across multiple tasks and unlock more advanced scene authoring confidence.
|
||||
|
||||
## What I Learned About Vanilla vs R3F vs Thob
|
||||
-
|
||||
- Vanilla three.js gives maximum control and predictable behavior, but requires more setup and deeper technical understanding.
|
||||
- R3F keeps most of Vanilla's control while making scene structure and updates cleaner through declarative components.
|
||||
- Thob is the fastest for initial visual authoring, but currently feels constrained for advanced workflows due to transform debugging gaps, limited duplication semantics, and lack of custom animation authoring.
|
||||
|
||||
Overall, Week 1 showed that Thob already has strong foundations for beginner and rapid prototyping workflows, but needs stronger transform tooling and deeper control surfaces to support production-level 3D interaction design.
|
||||
5
Week-2/Task-1/ProductLens.md
Normal file
5
Week-2/Task-1/ProductLens.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Product Lens
|
||||
- Is this pattern useful for real customers? Yes / Partial / No
|
||||
- What kind of customer use case does this support?
|
||||
- Does Thob feel strong enough for this use case?
|
||||
- What would improve the experience?
|
||||
60
Week-2/Task-1/TaskNotes.md
Normal file
60
Week-2/Task-1/TaskNotes.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Task: [Feature Name]
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
0
Week-2/Task-1/builder/BuilderNotes.md
Normal file
0
Week-2/Task-1/builder/BuilderNotes.md
Normal file
24
Week-2/Task-1/r3f/Cammera/.gitignore
vendored
Normal file
24
Week-2/Task-1/r3f/Cammera/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
16
Week-2/Task-1/r3f/Cammera/README.md
Normal file
16
Week-2/Task-1/r3f/Cammera/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
29
Week-2/Task-1/r3f/Cammera/eslint.config.js
Normal file
29
Week-2/Task-1/r3f/Cammera/eslint.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs.flat.recommended,
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
||||
},
|
||||
},
|
||||
])
|
||||
13
Week-2/Task-1/r3f/Cammera/index.html
Normal file
13
Week-2/Task-1/r3f/Cammera/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task1 R3f</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
30
Week-2/Task-1/r3f/Cammera/package.json
Normal file
30
Week-2/Task-1/r3f/Cammera/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "cammera",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.4.0",
|
||||
"vite": "^8.0.0"
|
||||
}
|
||||
}
|
||||
9
Week-2/Task-1/r3f/Cammera/src/App.jsx
Normal file
9
Week-2/Task-1/r3f/Cammera/src/App.jsx
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
15
Week-2/Task-1/r3f/Cammera/src/index.css
Normal file
15
Week-2/Task-1/r3f/Cammera/src/index.css
Normal file
@ -0,0 +1,15 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
10
Week-2/Task-1/r3f/Cammera/src/main.jsx
Normal file
10
Week-2/Task-1/r3f/Cammera/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
7
Week-2/Task-1/r3f/Cammera/vite.config.js
Normal file
7
Week-2/Task-1/r3f/Cammera/vite.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
1292
Week-2/Task-1/r3f/Cammera/yarn.lock
Normal file
1292
Week-2/Task-1/r3f/Cammera/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
12
Week-2/Task-1/r3f/package.json
Normal file
12
Week-2/Task-1/r3f/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "week-1-task-1-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your React Three Fiber dev script here'",
|
||||
"build": "echo 'Add your React Three Fiber build script here'",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build .next"
|
||||
}
|
||||
}
|
||||
19
Week-2/Task-1/vanilla/index.html
Normal file
19
Week-2/Task-1/vanilla/index.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Task1 vanilla </title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
background: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
0
Week-2/Task-1/vanilla/main.js
Normal file
0
Week-2/Task-1/vanilla/main.js
Normal file
18
Week-2/Task-1/vanilla/package.json
Normal file
18
Week-2/Task-1/vanilla/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "week-1-task-1-vanilla",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
},
|
||||
"dependencies": {
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^8.0.2"
|
||||
}
|
||||
}
|
||||
5
Week-2/Task-2/ProductLens.md
Normal file
5
Week-2/Task-2/ProductLens.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Product Lens
|
||||
- Is this pattern useful for real customers? Yes / Partial / No
|
||||
- What kind of customer use case does this support?
|
||||
- Does Thob feel strong enough for this use case?
|
||||
- What would improve the experience?
|
||||
60
Week-2/Task-2/TaskNotes.md
Normal file
60
Week-2/Task-2/TaskNotes.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Task: [Feature Name]
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
0
Week-2/Task-2/builder/BuilderNotes.md
Normal file
0
Week-2/Task-2/builder/BuilderNotes.md
Normal file
12
Week-2/Task-2/r3f/package.json
Normal file
12
Week-2/Task-2/r3f/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "week-1-task-2-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "echo 'Add your React Three Fiber dev script here'",
|
||||
"build": "echo 'Add your React Three Fiber build script here'",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build .next"
|
||||
}
|
||||
}
|
||||
24
Week-2/Task-2/r3f/sceene/.gitignore
vendored
Normal file
24
Week-2/Task-2/r3f/sceene/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
16
Week-2/Task-2/r3f/sceene/README.md
Normal file
16
Week-2/Task-2/r3f/sceene/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# React + Vite
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
|
||||
|
||||
## React Compiler
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
29
Week-2/Task-2/r3f/sceene/eslint.config.js
Normal file
29
Week-2/Task-2/r3f/sceene/eslint.config.js
Normal file
@ -0,0 +1,29 @@
|
||||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['dist']),
|
||||
{
|
||||
files: ['**/*.{js,jsx}'],
|
||||
extends: [
|
||||
js.configs.recommended,
|
||||
reactHooks.configs.flat.recommended,
|
||||
reactRefresh.configs.vite,
|
||||
],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
ecmaFeatures: { jsx: true },
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
||||
},
|
||||
},
|
||||
])
|
||||
13
Week-2/Task-2/r3f/sceene/index.html
Normal file
13
Week-2/Task-2/r3f/sceene/index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task2 R3f</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
2815
Week-2/Task-2/r3f/sceene/package-lock.json
generated
Normal file
2815
Week-2/Task-2/r3f/sceene/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
Week-2/Task-2/r3f/sceene/package.json
Normal file
29
Week-2/Task-2/r3f/sceene/package.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "sceene",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.4",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.5.2",
|
||||
"globals": "^17.4.0",
|
||||
"vite": "^8.0.0"
|
||||
}
|
||||
}
|
||||
8
Week-2/Task-2/r3f/sceene/src/App.jsx
Normal file
8
Week-2/Task-2/r3f/sceene/src/App.jsx
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
15
Week-2/Task-2/r3f/sceene/src/index.css
Normal file
15
Week-2/Task-2/r3f/sceene/src/index.css
Normal file
@ -0,0 +1,15 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
10
Week-2/Task-2/r3f/sceene/src/main.jsx
Normal file
10
Week-2/Task-2/r3f/sceene/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import App from './App.jsx'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
7
Week-2/Task-2/r3f/sceene/vite.config.js
Normal file
7
Week-2/Task-2/r3f/sceene/vite.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
28
Week-2/Task-2/vanilla/index.html
Normal file
28
Week-2/Task-2/vanilla/index.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Task2 vanilla</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
background: white;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body> <script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
0
Week-2/Task-2/vanilla/main.js
Normal file
0
Week-2/Task-2/vanilla/main.js
Normal file
18
Week-2/Task-2/vanilla/package.json
Normal file
18
Week-2/Task-2/vanilla/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "week-1-task-2-vanilla",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
},
|
||||
"dependencies": {
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
5
Week-2/Task-3/ProductLens.md
Normal file
5
Week-2/Task-3/ProductLens.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Product Lens
|
||||
- Is this pattern useful for real customers? Yes / Partial / No
|
||||
- What kind of customer use case does this support?
|
||||
- Does Thob feel strong enough for this use case?
|
||||
- What would improve the experience?
|
||||
60
Week-2/Task-3/TaskNotes.md
Normal file
60
Week-2/Task-3/TaskNotes.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Task: [Feature Name]
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
0
Week-2/Task-3/builder/BuilderNotes.md
Normal file
0
Week-2/Task-3/builder/BuilderNotes.md
Normal file
15
Week-2/Task-3/r3f/index.html
Normal file
15
Week-2/Task-3/r3f/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 3 R3F</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
24
Week-2/Task-3/r3f/package.json
Normal file
24
Week-2/Task-3/r3f/package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "week-1-task-3-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Lint not configured yet'",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist build .next"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
6
Week-2/Task-3/r3f/src/App.jsx
Normal file
6
Week-2/Task-3/r3f/src/App.jsx
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
18
Week-2/Task-3/r3f/src/index.css
Normal file
18
Week-2/Task-3/r3f/src/index.css
Normal file
@ -0,0 +1,18 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
background: #101418;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
10
Week-2/Task-3/r3f/src/main.jsx
Normal file
10
Week-2/Task-3/r3f/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
6
Week-2/Task-3/r3f/vite.config.js
Normal file
6
Week-2/Task-3/r3f/vite.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
24
Week-2/Task-3/vanilla/index.html
Normal file
24
Week-2/Task-3/vanilla/index.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 3 Vanilla</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #101418;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
0
Week-2/Task-3/vanilla/main.js
Normal file
0
Week-2/Task-3/vanilla/main.js
Normal file
12
Week-2/Task-3/vanilla/package.json
Normal file
12
Week-2/Task-3/vanilla/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "week-1-task-3-vanilla",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Add your lint script here'",
|
||||
"clean": "rm -rf dist build"
|
||||
}
|
||||
}
|
||||
5
Week-2/Task-4/ProductLens.md
Normal file
5
Week-2/Task-4/ProductLens.md
Normal file
@ -0,0 +1,5 @@
|
||||
## Product Lens
|
||||
- Is this pattern useful for real customers? Yes / Partial / No
|
||||
- What kind of customer use case does this support?
|
||||
- Does Thob feel strong enough for this use case?
|
||||
- What would improve the experience?
|
||||
60
Week-2/Task-4/TaskNotes.md
Normal file
60
Week-2/Task-4/TaskNotes.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Task: [Feature Name]
|
||||
|
||||
## Objective
|
||||
What is the feature trying to do?
|
||||
|
||||
## Vanilla three.js
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Key concepts:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## R3F
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-What R3F abstracted:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Thob Page Builder
|
||||
-Possible: Yes / Partial / No
|
||||
-Notes:
|
||||
-Builder steps:
|
||||
-Complexity: Easy / Medium / Hard
|
||||
|
||||
## Comparison Summary
|
||||
-Possible in all 3? Yes / Partial / No
|
||||
-Main differences:
|
||||
-Where Thob is better:
|
||||
-Where Thob is weaker:
|
||||
-What feels awkward or unclear:
|
||||
|
||||
## Limitation Type (if any)
|
||||
-[ ] Editor UX limitation
|
||||
-[ ] Runtime limitation
|
||||
-[ ] Schema / data model limitation
|
||||
-[ ] Component limitation
|
||||
-[ ] Event system limitation
|
||||
-[ ] Asset pipeline limitation
|
||||
-[ ] Unknown / needs investigation
|
||||
|
||||
## Workaround
|
||||
-Is there a workaround?
|
||||
-If yes, what is it?
|
||||
|
||||
## Suggested Improvement
|
||||
-What should improve in Thob?
|
||||
-Is it:
|
||||
-editor
|
||||
-runtime
|
||||
-component
|
||||
-UX
|
||||
-schema/data
|
||||
|
||||
## Difficulty Estimate
|
||||
-Easy / Medium / Hard
|
||||
|
||||
## Business Value
|
||||
-Low / Medium / High
|
||||
|
||||
## Recommendation
|
||||
Should Thob support this better? Why?
|
||||
73
Week-2/Task-4/builder/BuilderNotes.md
Normal file
73
Week-2/Task-4/builder/BuilderNotes.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Builder Notes (Thob) — Task 4: Basic Rotation / Motion
|
||||
|
||||
## Thob Observations from Task Notes
|
||||
|
||||
- **Possible:** Partial
|
||||
- **Implementation used:** Applied available built-in animation presets on a cube/object inside thob builder.
|
||||
- **What worked as expected:**
|
||||
- Preset animation can be applied quickly.
|
||||
- Basic motion effects are visible without writing code.
|
||||
- **Main limitation observed:**
|
||||
- Custom animation is not possible; only pre-provided animation can be applied.
|
||||
- Exact motion parity with Vanilla/R3F frame-loop logic is not achievable from the builder controls.
|
||||
- **Builder flow used:**
|
||||
1. Create/Add cube object in scene.
|
||||
2. Open animation controls.
|
||||
3. Apply available preset animation.
|
||||
4. Tune exposed preset options (for example speed/intensity where available).
|
||||
- **Complexity:** Easy for preset motion, hard for custom motion requirements.
|
||||
- **Main limitation signals:** Editor UX + Runtime + Component concerns.
|
||||
- **Workaround status:** Partial workaround only (use nearest preset); no true custom per-frame animation authoring.
|
||||
|
||||
## Console Warnings/Errors Seen (Deduplicated) and Probable Meaning
|
||||
|
||||
### warn: `Permissions-Policy header unrecognized feature ('browsing-topics')`
|
||||
- **Type:** Browser/header compatibility warning.
|
||||
- **Probable meaning:** Response header includes a policy directive not recognized by the current browser engine.
|
||||
- **Impact:** Usually low for scene editing itself; mostly platform/header noise.
|
||||
|
||||
### error: `GET https://builder.thob.studio/builder/<id> 404 (Not Found)`
|
||||
- **Type:** Network/resource error.
|
||||
- **Probable meaning:** Builder page/resource ID is stale, deleted, or inaccessible for current session.
|
||||
- **Impact:** High for workflow continuity; can block loading expected builder state.
|
||||
|
||||
### warn: `Unchecked runtime.lastError: The message port closed before a response was received`
|
||||
- **Type:** Browser extension/runtime messaging warning.
|
||||
- **Probable meaning:** A background messaging channel closed before callback response (often extension-related).
|
||||
- **Impact:** Usually low for core scene logic; can add debugging noise.
|
||||
|
||||
### warn: `No HydrateFallback element provided to render during initial hydration`
|
||||
- **Type:** Hydration/lifecycle warning.
|
||||
- **Probable meaning:** Initial hydration path expected a fallback UI element but none was configured.
|
||||
- **Impact:** Can produce unstable initial editor/preview rendering behavior.
|
||||
|
||||
### warn: `... changing from uncontrolled to controlled` and `RadioGroup is changing from uncontrolled to controlled`
|
||||
- **Type:** React state-management warning.
|
||||
- **Probable meaning:** Form/editor controls switch value ownership mode across renders.
|
||||
- **Impact:** Property panel behavior may become inconsistent or glitchy.
|
||||
|
||||
### warn: `GetBindingData<id> method already registered` (repeated)
|
||||
- **Type:** Duplicate registration warning.
|
||||
- **Probable meaning:** Binding method handlers are attached multiple times during rerender/remount cycles.
|
||||
- **Impact:** High log noise, risk of duplicated side effects, and potential performance degradation.
|
||||
|
||||
### warn: `resetPOI method already registered`
|
||||
- **Type:** Duplicate command registration warning.
|
||||
- **Probable meaning:** Command/event handler is registered more than once without cleanup.
|
||||
- **Impact:** Risk of repeated command execution and state drift.
|
||||
|
||||
### warn: `camera-controls: verticalDragToForward was removed...`
|
||||
- **Type:** API deprecation/removed option warning.
|
||||
- **Probable meaning:** Legacy camera-controls prop is still being used by some path in the runtime/editor.
|
||||
- **Impact:** Non-fatal now, but indicates outdated control configuration and future fragility.
|
||||
|
||||
### error: `THREE.GLTFLoader: Invalid plugin found: missing name`
|
||||
- **Type:** Asset loader/plugin configuration error.
|
||||
- **Probable meaning:** GLTF loader plugin object does not satisfy required shape/metadata.
|
||||
- **Impact:** Asset loading behavior may be incomplete or fail for some models.
|
||||
|
||||
## Overall Read
|
||||
|
||||
- For Task 4, thob supports only preset motion and does not support custom animation logic, which is the core functional gap compared with Vanilla and R3F.
|
||||
- Console output shows repeated registration and controlled/uncontrolled warnings, which aligns with editor/runtime stability concerns when iterating quickly in builder.
|
||||
- The 404 page load and loader/control warnings suggest platform-level reliability and compatibility issues that can interfere with smooth motion-authoring workflows.
|
||||
15
Week-2/Task-4/r3f/index.html
Normal file
15
Week-2/Task-4/r3f/index.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Task 4 R3F</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
24
Week-2/Task-4/r3f/package.json
Normal file
24
Week-2/Task-4/r3f/package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "week-1-task-4-r3f",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"packageManager": "yarn@1.22.22",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "echo 'Lint not configured yet'",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist build .next"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"three": "^0.183.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^6.0.0",
|
||||
"vite": "^8.0.3"
|
||||
}
|
||||
}
|
||||
6
Week-2/Task-4/r3f/src/App.jsx
Normal file
6
Week-2/Task-4/r3f/src/App.jsx
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
8
Week-2/Task-4/r3f/src/index.css
Normal file
8
Week-2/Task-4/r3f/src/index.css
Normal file
@ -0,0 +1,8 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background-color: black;
|
||||
}
|
||||
10
Week-2/Task-4/r3f/src/main.jsx
Normal file
10
Week-2/Task-4/r3f/src/main.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
|
||||
createRoot(document.getElementById('root')).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
6
Week-2/Task-4/r3f/vite.config.js
Normal file
6
Week-2/Task-4/r3f/vite.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user