refactor: extract PixiJS rendering into pixi/ modules
Phase 5 (behavior-preserving): decompose the ~1000-line onMount into focused
modules coordinated by a plain (non-reactive) controller object:
- pixi/types.ts LineObject / NodeObject / BackgroundLayers
- pixi/controller.ts shared mutable pan/zoom state + Pixi refs (NOT $state,
which would break PixiJS object identity)
- pixi/background.ts gradient/nebula/stars/dust/vignette + ambient loops
- pixi/lines.ts plasma-beam connections
- pixi/nodes.ts origin + regular nodes; collapses the duplicated pointer
handlers into one attachNodeInteraction helper
- pixi/interaction.ts pan/zoom/parallax + keyboard nav (return cleanups)
- pixi/animation.ts sequenced entrance animation
onMount is now a thin orchestrator. SkillTree.svelte: 1177 -> 274 lines
(2453 at the start of the refactor). Listener passivity, the hasMoved click
guard, eventMode-until-animated ordering, and the R-reset parallax rebaseline
are all preserved.
svelte-check: 0 errors/0 warnings. lint/test/build clean. Verified onMount runs
with no runtime exceptions (background + stats panel render). NOTE: pan/zoom/
node-click/keyboard need a manual real-browser check (headless can't paint nodes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f08138718a
commit
84112d8e42
8 files changed
+1057
-946
No files matched your search
@@ -0,0 +1,58 @@
|
||||
// Mutable controller object shared across the PixiJS modules.
|
||||
//
|
||||
// IMPORTANT: this must NOT be wrapped in Svelte's `$state` — the deep proxy
|
||||
// breaks PixiJS's internal object identity checks. Keep it a plain object so
|
||||
// the interaction, node, and animation modules can read/write the same
|
||||
// mutable pan/zoom state by reference (the same single source of truth the
|
||||
// original onMount closure relied on).
|
||||
import type { Application, Container } from 'pixi.js';
|
||||
import type { BackgroundLayers, LineObject, NodeObject } from './types';
|
||||
|
||||
export interface SkillTreeController {
|
||||
app: Application;
|
||||
treeContainer: Container;
|
||||
bg: BackgroundLayers;
|
||||
nodeObjects: NodeObject[];
|
||||
lineObjects: LineObject[];
|
||||
|
||||
// Pan/zoom mutable state (was closure vars in onMount).
|
||||
isDragging: boolean;
|
||||
hasMoved: boolean;
|
||||
dragStartX: number;
|
||||
dragStartY: number;
|
||||
containerStartX: number;
|
||||
containerStartY: number;
|
||||
lastTouchDistance: number;
|
||||
isTouchZooming: boolean;
|
||||
|
||||
// Parallax baseline (re-set on view reset) + final zoom scale.
|
||||
initialTreeX: number;
|
||||
initialTreeY: number;
|
||||
endScale: number;
|
||||
}
|
||||
|
||||
export function createController(
|
||||
app: Application,
|
||||
treeContainer: Container,
|
||||
bg: BackgroundLayers,
|
||||
endScale: number
|
||||
): SkillTreeController {
|
||||
return {
|
||||
app,
|
||||
treeContainer,
|
||||
bg,
|
||||
nodeObjects: [],
|
||||
lineObjects: [],
|
||||
isDragging: false,
|
||||
hasMoved: false,
|
||||
dragStartX: 0,
|
||||
dragStartY: 0,
|
||||
containerStartX: 0,
|
||||
containerStartY: 0,
|
||||
lastTouchDistance: 0,
|
||||
isTouchZooming: false,
|
||||
initialTreeX: treeContainer.x,
|
||||
initialTreeY: treeContainer.y,
|
||||
endScale
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user