V2: Origin based animations, Gesture Builder, New Demo, non-url-based-routing. Massive improvements.
This commit is contained in:
105
docs/routeless-origins.md
Normal file
105
docs/routeless-origins.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Routeless origins architecture
|
||||
|
||||
The v2 experiment lives in `packages/core-v2` and its physical test application
|
||||
lives in `apps/origins-demo`.
|
||||
|
||||
## State model
|
||||
|
||||
The scene contains:
|
||||
|
||||
- stable, flat Vue component nodes;
|
||||
- linked mounted-instance history entries;
|
||||
- temporary directed operation edges.
|
||||
|
||||
It does not contain an active route or current view.
|
||||
|
||||
For overlapping operations:
|
||||
|
||||
```text
|
||||
Nodes: X, Y, Z
|
||||
Edges: X → Y
|
||||
Y → Z
|
||||
```
|
||||
|
||||
Each edge records its own progress, velocity, outcome, choreography, and
|
||||
source/target keys.
|
||||
|
||||
## Coordinate composition
|
||||
|
||||
Suppose A is X→Y and B is Y→Z:
|
||||
|
||||
```text
|
||||
visual(X) = A.source
|
||||
visual(Y) = A.target × B.source
|
||||
visual(Z) = A.target × B.target
|
||||
```
|
||||
|
||||
An optional frame effect is included on both sides of an edge:
|
||||
|
||||
```text
|
||||
visual(Y) = A.frame × A.target × B.frame × B.source
|
||||
visual(Z) = A.frame × A.target × B.frame × B.target
|
||||
```
|
||||
|
||||
The implementation emits these operations as one combined transform on each
|
||||
flat host. This has the visual semantics of nested coordinate frames without
|
||||
reparenting Vue component VNodes.
|
||||
|
||||
## Completion
|
||||
|
||||
Committing a forward X→Y:
|
||||
|
||||
1. Keeps X mounted but marks it parked, inert, and visually hidden.
|
||||
2. Places Y in X's former visual graph position.
|
||||
3. Removes the X→Y edge.
|
||||
4. Leaves any Y→Z edge and all mounted descendants intact.
|
||||
|
||||
Committing Y→Z before X→Y is also valid. Z replaces Y as the target of the
|
||||
still-running X edge, after which X→Y effectively becomes X→Z. The unit suite
|
||||
covers both completion orders.
|
||||
|
||||
Committing back from Y to X reveals the existing X node and removes Y. It does
|
||||
not construct X again from its recipe. Cancelling a forward edge restores its
|
||||
source and removes the newly created target branch; cancelling a back edge
|
||||
re-parks its retained target.
|
||||
|
||||
## Interaction
|
||||
|
||||
Gesture recognition is declared within each component through
|
||||
`OriginGesture` or `useOriginGesture()`. The injected scene-node key determines
|
||||
the origin. Recognition never asks a coordinator which view is active.
|
||||
|
||||
The immutable `gesture` builder separates optional pointer-down policy
|
||||
(`.from`), movement recognition (`.to`), release policy (`.complete`),
|
||||
navigation intent (`.navigate`), and visual choreography (`.animate`). A chain
|
||||
that begins at `.to` is valid and admits pointer-down anywhere on its host.
|
||||
|
||||
At pointer release, the operation decides synchronously whether it will commit
|
||||
or cancel. Its spring may continue afterward. A retained target can therefore
|
||||
originate another routine while the preceding spring is still visible.
|
||||
|
||||
### Nested scenes
|
||||
|
||||
An `OriginScene` may be rendered inside a view owned by another scene. The
|
||||
nearest injected node scope makes carousel or deck gestures operate on the
|
||||
nested scene, with local measurements and retained history.
|
||||
|
||||
Gesture ownership between nested scenes is currently selected at pointer-down.
|
||||
An eligible child stops propagation even if its later navigation factory
|
||||
declines. Parent fallback therefore requires the child to reserve a
|
||||
non-matching `.from` region; automatic delayed arbitration remains future
|
||||
gesture-arena work.
|
||||
|
||||
## Retained history
|
||||
|
||||
Each pushed node stores the key of its mounted previous entry. The chain is
|
||||
local to that origin context rather than a URL:
|
||||
|
||||
```text
|
||||
X (parked) ← Y (parked) ← Z (visible)
|
||||
```
|
||||
|
||||
Back targets the previous node key directly. A node is unmounted only when a
|
||||
committed back operation pops it, a forward operation is cancelled, or the
|
||||
whole scene is destroyed. Because the same DOM survives parking, nested scroll
|
||||
positions and component-local state survive without `<KeepAlive>`.
|
||||
Reference in New Issue
Block a user