@vib3code/sdk 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +118 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
- package/DOCS/CI_TESTING.md +38 -0
- package/DOCS/CLI_ONBOARDING.md +75 -0
- package/DOCS/CONTROL_REFERENCE.md +64 -0
- package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
- package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
- package/DOCS/ENV_SETUP.md +189 -0
- package/DOCS/EXPORT_FORMATS.md +417 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
- package/DOCS/LICENSING_TIERS.md +275 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
- package/DOCS/OBS_SETUP_GUIDE.md +98 -0
- package/DOCS/PROJECT_SETUP.md +66 -0
- package/DOCS/RENDERER_LIFECYCLE.md +40 -0
- package/DOCS/REPO_MANIFEST.md +121 -0
- package/DOCS/SESSION_014_PLAN.md +195 -0
- package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
- package/DOCS/SYSTEM_INVENTORY.md +520 -0
- package/DOCS/TELEMETRY_EXPORTS.md +34 -0
- package/DOCS/WEBGPU_STATUS.md +38 -0
- package/DOCS/XR_BENCHMARKS.md +608 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/docs/.nojekyll +0 -0
- package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/02-hyperspatial_ego_death.html +346 -0
- package/docs/03-post_cartesian_sublime.html +346 -0
- package/docs/04-crystalline_void_meditation.html +346 -0
- package/docs/05-quantum_decoherence_ballet.html +346 -0
- package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/07-hyperspatial_ego_death.html +346 -0
- package/docs/08-post_cartesian_sublime.html +346 -0
- package/docs/09-crystalline_void_meditation.html +346 -0
- package/docs/10-quantum_decoherence_ballet.html +346 -0
- package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/12-hyperspatial_ego_death.html +346 -0
- package/docs/13-post_cartesian_sublime.html +346 -0
- package/docs/index.html +794 -0
- package/docs/test-hub.html +441 -0
- package/docs/url-state.js +102 -0
- package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
- package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
- package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
- package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
- package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
- package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
- package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
- package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
- package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
- package/docs/vib3-exports/index.html +238 -0
- package/docs/webgpu-live.html +702 -0
- package/package.json +367 -0
- package/src/advanced/AIPresetGenerator.js +777 -0
- package/src/advanced/MIDIController.js +703 -0
- package/src/advanced/OffscreenWorker.js +1051 -0
- package/src/advanced/WebGPUCompute.js +1051 -0
- package/src/advanced/WebXRRenderer.js +680 -0
- package/src/agent/cli/AgentCLI.js +615 -0
- package/src/agent/cli/index.js +14 -0
- package/src/agent/index.js +73 -0
- package/src/agent/mcp/MCPServer.js +950 -0
- package/src/agent/mcp/index.js +9 -0
- package/src/agent/mcp/tools.js +548 -0
- package/src/agent/telemetry/EventStream.js +669 -0
- package/src/agent/telemetry/Instrumentation.js +618 -0
- package/src/agent/telemetry/TelemetryExporters.js +427 -0
- package/src/agent/telemetry/TelemetryService.js +464 -0
- package/src/agent/telemetry/index.js +52 -0
- package/src/benchmarks/BenchmarkRunner.js +381 -0
- package/src/benchmarks/MetricsCollector.js +299 -0
- package/src/benchmarks/index.js +9 -0
- package/src/benchmarks/scenes.js +259 -0
- package/src/cli/index.js +675 -0
- package/src/config/ApiConfig.js +88 -0
- package/src/core/CanvasManager.js +217 -0
- package/src/core/ErrorReporter.js +117 -0
- package/src/core/ParameterMapper.js +333 -0
- package/src/core/Parameters.js +396 -0
- package/src/core/RendererContracts.js +200 -0
- package/src/core/UnifiedResourceManager.js +370 -0
- package/src/core/VIB3Engine.js +636 -0
- package/src/core/renderers/FacetedRendererAdapter.js +32 -0
- package/src/core/renderers/HolographicRendererAdapter.js +29 -0
- package/src/core/renderers/QuantumRendererAdapter.js +29 -0
- package/src/core/renderers/RendererLifecycleManager.js +63 -0
- package/src/creative/ColorPresetsSystem.js +980 -0
- package/src/creative/ParameterTimeline.js +1061 -0
- package/src/creative/PostProcessingPipeline.js +1113 -0
- package/src/creative/TransitionAnimator.js +683 -0
- package/src/export/CSSExporter.js +226 -0
- package/src/export/CardGeneratorBase.js +279 -0
- package/src/export/ExportManager.js +580 -0
- package/src/export/FacetedCardGenerator.js +279 -0
- package/src/export/HolographicCardGenerator.js +543 -0
- package/src/export/LottieExporter.js +552 -0
- package/src/export/QuantumCardGenerator.js +315 -0
- package/src/export/SVGExporter.js +519 -0
- package/src/export/ShaderExporter.js +903 -0
- package/src/export/TradingCardGenerator.js +3055 -0
- package/src/export/TradingCardManager.js +181 -0
- package/src/export/VIB3PackageExporter.js +559 -0
- package/src/export/index.js +14 -0
- package/src/export/systems/TradingCardSystemFaceted.js +494 -0
- package/src/export/systems/TradingCardSystemHolographic.js +452 -0
- package/src/export/systems/TradingCardSystemQuantum.js +411 -0
- package/src/faceted/FacetedSystem.js +963 -0
- package/src/features/CollectionManager.js +433 -0
- package/src/gallery/CollectionManager.js +240 -0
- package/src/gallery/GallerySystem.js +485 -0
- package/src/geometry/GeometryFactory.js +314 -0
- package/src/geometry/GeometryLibrary.js +72 -0
- package/src/geometry/buffers/BufferBuilder.js +338 -0
- package/src/geometry/buffers/index.js +18 -0
- package/src/geometry/generators/Crystal.js +420 -0
- package/src/geometry/generators/Fractal.js +298 -0
- package/src/geometry/generators/KleinBottle.js +197 -0
- package/src/geometry/generators/Sphere.js +192 -0
- package/src/geometry/generators/Tesseract.js +160 -0
- package/src/geometry/generators/Tetrahedron.js +225 -0
- package/src/geometry/generators/Torus.js +304 -0
- package/src/geometry/generators/Wave.js +341 -0
- package/src/geometry/index.js +142 -0
- package/src/geometry/warp/HypersphereCore.js +211 -0
- package/src/geometry/warp/HypertetraCore.js +386 -0
- package/src/geometry/warp/index.js +57 -0
- package/src/holograms/HolographicVisualizer.js +1073 -0
- package/src/holograms/RealHolographicSystem.js +966 -0
- package/src/holograms/variantRegistry.js +69 -0
- package/src/integrations/FigmaPlugin.js +854 -0
- package/src/integrations/OBSMode.js +754 -0
- package/src/integrations/ThreeJsPackage.js +660 -0
- package/src/integrations/TouchDesignerExport.js +552 -0
- package/src/integrations/frameworks/Vib3React.js +591 -0
- package/src/integrations/frameworks/Vib3Svelte.js +654 -0
- package/src/integrations/frameworks/Vib3Vue.js +628 -0
- package/src/llm/LLMParameterInterface.js +240 -0
- package/src/llm/LLMParameterUI.js +577 -0
- package/src/math/Mat4x4.js +708 -0
- package/src/math/Projection.js +341 -0
- package/src/math/Rotor4D.js +637 -0
- package/src/math/Vec4.js +476 -0
- package/src/math/constants.js +164 -0
- package/src/math/index.js +68 -0
- package/src/math/projections.js +54 -0
- package/src/math/rotations.js +196 -0
- package/src/quantum/QuantumEngine.js +906 -0
- package/src/quantum/QuantumVisualizer.js +1103 -0
- package/src/reactivity/ReactivityConfig.js +499 -0
- package/src/reactivity/ReactivityManager.js +586 -0
- package/src/reactivity/SpatialInputSystem.js +1783 -0
- package/src/reactivity/index.js +93 -0
- package/src/render/CommandBuffer.js +465 -0
- package/src/render/MultiCanvasBridge.js +340 -0
- package/src/render/RenderCommand.js +514 -0
- package/src/render/RenderResourceRegistry.js +523 -0
- package/src/render/RenderState.js +552 -0
- package/src/render/RenderTarget.js +512 -0
- package/src/render/ShaderLoader.js +253 -0
- package/src/render/ShaderProgram.js +599 -0
- package/src/render/UnifiedRenderBridge.js +496 -0
- package/src/render/backends/WebGLBackend.js +1108 -0
- package/src/render/backends/WebGPUBackend.js +1409 -0
- package/src/render/commands/CommandBufferExecutor.js +607 -0
- package/src/render/commands/RenderCommandBuffer.js +661 -0
- package/src/render/commands/index.js +17 -0
- package/src/render/index.js +367 -0
- package/src/scene/Disposable.js +498 -0
- package/src/scene/MemoryPool.js +618 -0
- package/src/scene/Node4D.js +697 -0
- package/src/scene/ResourceManager.js +599 -0
- package/src/scene/Scene4D.js +540 -0
- package/src/scene/index.js +98 -0
- package/src/schemas/error.schema.json +84 -0
- package/src/schemas/extension.schema.json +88 -0
- package/src/schemas/index.js +214 -0
- package/src/schemas/parameters.schema.json +142 -0
- package/src/schemas/tool-pack.schema.json +44 -0
- package/src/schemas/tool-response.schema.json +127 -0
- package/src/shaders/common/fullscreen.vert.glsl +5 -0
- package/src/shaders/common/fullscreen.vert.wgsl +17 -0
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +85 -0
- package/src/shaders/common/rotation4d.wgsl +86 -0
- package/src/shaders/common/uniforms.glsl +44 -0
- package/src/shaders/common/uniforms.wgsl +48 -0
- package/src/shaders/faceted/faceted.frag.glsl +129 -0
- package/src/shaders/faceted/faceted.frag.wgsl +164 -0
- package/src/shaders/holographic/holographic.frag.glsl +406 -0
- package/src/shaders/holographic/holographic.frag.wgsl +185 -0
- package/src/shaders/quantum/quantum.frag.glsl +513 -0
- package/src/shaders/quantum/quantum.frag.wgsl +361 -0
- package/src/testing/ParallelTestFramework.js +519 -0
- package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
- package/src/testing/exportFormats.test.js +8 -0
- package/src/testing/projections.test.js +14 -0
- package/src/testing/rotations.test.js +37 -0
- package/src/ui/InteractivityMenu.js +516 -0
- package/src/ui/StatusManager.js +96 -0
- package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
- package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
- package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
- package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
- package/src/variations/VariationManager.js +431 -0
- package/src/viewer/AudioReactivity.js +505 -0
- package/src/viewer/CardBending.js +481 -0
- package/src/viewer/GalleryUI.js +832 -0
- package/src/viewer/ReactivityManager.js +590 -0
- package/src/viewer/TradingCardExporter.js +600 -0
- package/src/viewer/ViewerPortal.js +374 -0
- package/src/viewer/index.js +12 -0
- package/src/wasm/WasmLoader.js +296 -0
- package/src/wasm/index.js +132 -0
- package/tools/agentic/mcpTools.js +88 -0
- package/tools/cli/agent-cli.js +92 -0
- package/tools/export/formats.js +24 -0
- package/tools/math/rotation-baseline.mjs +64 -0
- package/tools/shader-sync-verify.js +937 -0
- package/tools/telemetry/manifestPipeline.js +141 -0
- package/tools/telemetry/telemetryEvents.js +35 -0
- package/types/adaptive-sdk.d.ts +185 -0
- package/types/advanced/AIPresetGenerator.d.ts +81 -0
- package/types/advanced/MIDIController.d.ts +100 -0
- package/types/advanced/OffscreenWorker.d.ts +82 -0
- package/types/advanced/WebGPUCompute.d.ts +52 -0
- package/types/advanced/WebXRRenderer.d.ts +77 -0
- package/types/advanced/index.d.ts +46 -0
- package/types/core/ErrorReporter.d.ts +50 -0
- package/types/core/VIB3Engine.d.ts +204 -0
- package/types/creative/ColorPresetsSystem.d.ts +91 -0
- package/types/creative/ParameterTimeline.d.ts +74 -0
- package/types/creative/PostProcessingPipeline.d.ts +109 -0
- package/types/creative/TransitionAnimator.d.ts +71 -0
- package/types/creative/index.d.ts +35 -0
- package/types/integrations/FigmaPlugin.d.ts +46 -0
- package/types/integrations/OBSMode.d.ts +74 -0
- package/types/integrations/ThreeJsPackage.d.ts +62 -0
- package/types/integrations/TouchDesignerExport.d.ts +36 -0
- package/types/integrations/Vib3React.d.ts +74 -0
- package/types/integrations/Vib3Svelte.d.ts +63 -0
- package/types/integrations/Vib3Vue.d.ts +55 -0
- package/types/integrations/index.d.ts +52 -0
- package/types/reactivity/SpatialInputSystem.d.ts +173 -0
- package/types/reactivity/index.d.ts +394 -0
- package/types/render/CommandBuffer.d.ts +169 -0
- package/types/render/RenderCommand.d.ts +312 -0
- package/types/render/RenderState.d.ts +279 -0
- package/types/render/RenderTarget.d.ts +254 -0
- package/types/render/ShaderProgram.d.ts +277 -0
- package/types/render/UnifiedRenderBridge.d.ts +143 -0
- package/types/render/WebGLBackend.d.ts +168 -0
- package/types/render/WebGPUBackend.d.ts +186 -0
- package/types/render/index.d.ts +141 -0
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VIB34D Gallery System
|
|
3
|
+
* Portfolio view with live hover previews and variation browsing
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export class GallerySystem {
|
|
7
|
+
constructor(engine) {
|
|
8
|
+
this.engine = engine;
|
|
9
|
+
this.galleryModal = null;
|
|
10
|
+
this.previewCanvas = null;
|
|
11
|
+
this.previewVisualizer = null;
|
|
12
|
+
this.currentPreview = -1;
|
|
13
|
+
this.previewTimeout = null;
|
|
14
|
+
|
|
15
|
+
this.init();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialize gallery system
|
|
20
|
+
*/
|
|
21
|
+
init() {
|
|
22
|
+
this.createGalleryModal();
|
|
23
|
+
this.setupEventHandlers();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Create gallery modal HTML structure
|
|
28
|
+
*/
|
|
29
|
+
createGalleryModal() {
|
|
30
|
+
const modal = document.createElement('div');
|
|
31
|
+
modal.id = 'galleryModal';
|
|
32
|
+
modal.className = 'modal gallery-modal';
|
|
33
|
+
|
|
34
|
+
modal.innerHTML = `
|
|
35
|
+
<div class="modal-content gallery-content">
|
|
36
|
+
<div class="gallery-header">
|
|
37
|
+
<h2>VIB34D Variation Gallery</h2>
|
|
38
|
+
<div class="gallery-controls">
|
|
39
|
+
<button class="preview-toggle" title="Toggle Live Preview">
|
|
40
|
+
<span class="icon">👁️</span> Live Preview
|
|
41
|
+
</button>
|
|
42
|
+
<button class="gallery-export" title="Export All Variations">
|
|
43
|
+
<span class="icon">📁</span> Export All
|
|
44
|
+
</button>
|
|
45
|
+
<button class="close-btn" title="Close Gallery">×</button>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="gallery-body">
|
|
50
|
+
<div class="gallery-sidebar">
|
|
51
|
+
<div class="preview-container">
|
|
52
|
+
<canvas id="galleryPreviewCanvas" width="300" height="300"></canvas>
|
|
53
|
+
<div class="preview-info">
|
|
54
|
+
<div class="preview-title">Hover to preview</div>
|
|
55
|
+
<div class="preview-details"></div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div class="gallery-stats">
|
|
60
|
+
<div class="stat-item">
|
|
61
|
+
<span class="stat-label">Total Variations:</span>
|
|
62
|
+
<span class="stat-value" id="totalVariationsCount">100</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="stat-item">
|
|
65
|
+
<span class="stat-label">Custom Variations:</span>
|
|
66
|
+
<span class="stat-value" id="customVariationsCount">0</span>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="gallery-grid-container">
|
|
72
|
+
<div class="gallery-sections">
|
|
73
|
+
<!-- Populated dynamically -->
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
document.body.appendChild(modal);
|
|
81
|
+
this.galleryModal = modal;
|
|
82
|
+
|
|
83
|
+
// Get preview canvas
|
|
84
|
+
this.previewCanvas = document.getElementById('galleryPreviewCanvas');
|
|
85
|
+
this.initPreviewSystem();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Initialize preview system
|
|
90
|
+
*/
|
|
91
|
+
initPreviewSystem() {
|
|
92
|
+
if (this.previewCanvas) {
|
|
93
|
+
// Create a preview visualizer (simplified version)
|
|
94
|
+
this.previewVisualizer = {
|
|
95
|
+
canvas: this.previewCanvas,
|
|
96
|
+
ctx: this.previewCanvas.getContext('2d'),
|
|
97
|
+
params: {},
|
|
98
|
+
|
|
99
|
+
updateParams(params) {
|
|
100
|
+
this.params = { ...params };
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
render() {
|
|
104
|
+
const ctx = this.ctx;
|
|
105
|
+
const canvas = this.canvas;
|
|
106
|
+
|
|
107
|
+
// Clear canvas
|
|
108
|
+
ctx.fillStyle = '#000';
|
|
109
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
110
|
+
|
|
111
|
+
// Simple geometric preview based on parameters
|
|
112
|
+
const centerX = canvas.width / 2;
|
|
113
|
+
const centerY = canvas.height / 2;
|
|
114
|
+
const time = Date.now() * 0.001;
|
|
115
|
+
|
|
116
|
+
// Generate preview pattern
|
|
117
|
+
for (let i = 0; i < this.params.gridDensity * 5; i++) {
|
|
118
|
+
const angle = (i / (this.params.gridDensity * 5)) * Math.PI * 2;
|
|
119
|
+
const radius = Math.sin(time * this.params.speed + angle * this.params.morphFactor) * 80;
|
|
120
|
+
|
|
121
|
+
const x = centerX + Math.cos(angle) * radius;
|
|
122
|
+
const y = centerY + Math.sin(angle) * radius;
|
|
123
|
+
|
|
124
|
+
const hue = (this.params.hue + angle * 57.2958 + time * 20) % 360;
|
|
125
|
+
const alpha = 0.4 + Math.sin(time * 2 + angle) * 0.3;
|
|
126
|
+
|
|
127
|
+
ctx.fillStyle = `hsla(${hue}, 70%, 50%, ${alpha})`;
|
|
128
|
+
ctx.beginPath();
|
|
129
|
+
ctx.arc(x, y, 2 + this.params.chaos * 4, 0, Math.PI * 2);
|
|
130
|
+
ctx.fill();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Start preview render loop
|
|
136
|
+
const previewRender = () => {
|
|
137
|
+
if (this.currentPreview >= 0) {
|
|
138
|
+
this.previewVisualizer.render();
|
|
139
|
+
}
|
|
140
|
+
requestAnimationFrame(previewRender);
|
|
141
|
+
};
|
|
142
|
+
previewRender();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Set up event handlers
|
|
148
|
+
*/
|
|
149
|
+
setupEventHandlers() {
|
|
150
|
+
// Close button
|
|
151
|
+
const closeBtn = this.galleryModal.querySelector('.close-btn');
|
|
152
|
+
closeBtn.addEventListener('click', () => this.closeGallery());
|
|
153
|
+
|
|
154
|
+
// Close on backdrop click
|
|
155
|
+
this.galleryModal.addEventListener('click', (e) => {
|
|
156
|
+
if (e.target === this.galleryModal) {
|
|
157
|
+
this.closeGallery();
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Preview toggle
|
|
162
|
+
const previewToggle = this.galleryModal.querySelector('.preview-toggle');
|
|
163
|
+
previewToggle.addEventListener('click', () => {
|
|
164
|
+
this.togglePreview();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Export all button
|
|
168
|
+
const exportBtn = this.galleryModal.querySelector('.gallery-export');
|
|
169
|
+
exportBtn.addEventListener('click', () => {
|
|
170
|
+
this.exportAllVariations();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Keyboard navigation
|
|
174
|
+
document.addEventListener('keydown', (e) => {
|
|
175
|
+
if (this.galleryModal.classList.contains('active')) {
|
|
176
|
+
switch (e.key) {
|
|
177
|
+
case 'Escape':
|
|
178
|
+
this.closeGallery();
|
|
179
|
+
break;
|
|
180
|
+
case 'ArrowLeft':
|
|
181
|
+
this.navigatePreview(-1);
|
|
182
|
+
break;
|
|
183
|
+
case 'ArrowRight':
|
|
184
|
+
this.navigatePreview(1);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Open gallery modal
|
|
193
|
+
*/
|
|
194
|
+
openGallery() {
|
|
195
|
+
this.populateGallery();
|
|
196
|
+
this.updateGalleryStats();
|
|
197
|
+
this.galleryModal.classList.add('active');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Close gallery modal
|
|
202
|
+
*/
|
|
203
|
+
closeGallery() {
|
|
204
|
+
this.galleryModal.classList.remove('active');
|
|
205
|
+
this.currentPreview = -1;
|
|
206
|
+
this.clearPreview();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Populate gallery with variation thumbnails
|
|
211
|
+
*/
|
|
212
|
+
populateGallery() {
|
|
213
|
+
const sectionsContainer = this.galleryModal.querySelector('.gallery-sections');
|
|
214
|
+
sectionsContainer.innerHTML = '';
|
|
215
|
+
|
|
216
|
+
// Create sections for each geometry type
|
|
217
|
+
const geometryTypes = [
|
|
218
|
+
{ name: 'Tetrahedron Lattice', range: [0, 3], class: 'tetrahedron' },
|
|
219
|
+
{ name: 'Hypercube Lattice', range: [4, 7], class: 'hypercube' },
|
|
220
|
+
{ name: 'Sphere Lattice', range: [8, 11], class: 'sphere' },
|
|
221
|
+
{ name: 'Torus Lattice', range: [12, 15], class: 'torus' },
|
|
222
|
+
{ name: 'Klein Bottle Lattice', range: [16, 19], class: 'klein' },
|
|
223
|
+
{ name: 'Fractal Lattice', range: [20, 22], class: 'fractal' },
|
|
224
|
+
{ name: 'Wave Lattice', range: [23, 25], class: 'wave' },
|
|
225
|
+
{ name: 'Crystal Lattice', range: [26, 29], class: 'crystal' }
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
// Add default geometry sections
|
|
229
|
+
geometryTypes.forEach(geomType => {
|
|
230
|
+
const section = this.createGallerySection(geomType.name, geomType.range, geomType.class, true);
|
|
231
|
+
sectionsContainer.appendChild(section);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Add custom variations section
|
|
235
|
+
const customSection = this.createCustomGallerySection();
|
|
236
|
+
sectionsContainer.appendChild(customSection);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Create gallery section for geometry type
|
|
241
|
+
*/
|
|
242
|
+
createGallerySection(name, range, className, isDefault) {
|
|
243
|
+
const section = document.createElement('div');
|
|
244
|
+
section.className = 'gallery-section';
|
|
245
|
+
|
|
246
|
+
const header = document.createElement('h3');
|
|
247
|
+
header.textContent = name;
|
|
248
|
+
header.className = `geometry-header ${className}`;
|
|
249
|
+
|
|
250
|
+
const grid = document.createElement('div');
|
|
251
|
+
grid.className = 'gallery-grid';
|
|
252
|
+
|
|
253
|
+
for (let i = range[0]; i <= range[1]; i++) {
|
|
254
|
+
if (i < this.engine.variationManager.variationNames.length || !isDefault) {
|
|
255
|
+
const thumbnail = this.createVariationThumbnail(i, isDefault);
|
|
256
|
+
grid.appendChild(thumbnail);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
section.appendChild(header);
|
|
261
|
+
section.appendChild(grid);
|
|
262
|
+
|
|
263
|
+
return section;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Create custom variations gallery section
|
|
268
|
+
*/
|
|
269
|
+
createCustomGallerySection() {
|
|
270
|
+
const section = document.createElement('div');
|
|
271
|
+
section.className = 'gallery-section custom-section';
|
|
272
|
+
|
|
273
|
+
const header = document.createElement('h3');
|
|
274
|
+
header.textContent = 'Custom Variations';
|
|
275
|
+
header.className = 'geometry-header custom';
|
|
276
|
+
|
|
277
|
+
const grid = document.createElement('div');
|
|
278
|
+
grid.className = 'gallery-grid custom-grid';
|
|
279
|
+
|
|
280
|
+
// Show only populated custom variations
|
|
281
|
+
for (let i = 0; i < 70; i++) {
|
|
282
|
+
const customVar = this.engine.variationManager.customVariations[i];
|
|
283
|
+
if (customVar) {
|
|
284
|
+
const thumbnail = this.createVariationThumbnail(30 + i, false);
|
|
285
|
+
grid.appendChild(thumbnail);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
section.appendChild(header);
|
|
290
|
+
section.appendChild(grid);
|
|
291
|
+
|
|
292
|
+
return section;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Create individual variation thumbnail
|
|
297
|
+
*/
|
|
298
|
+
createVariationThumbnail(index, isDefault) {
|
|
299
|
+
const thumbnail = document.createElement('div');
|
|
300
|
+
thumbnail.className = `gallery-thumbnail ${isDefault ? 'default' : 'custom'}`;
|
|
301
|
+
thumbnail.dataset.variation = index;
|
|
302
|
+
|
|
303
|
+
const name = this.engine.variationManager.getVariationName(index);
|
|
304
|
+
const isCurrent = index === this.engine.currentVariation;
|
|
305
|
+
|
|
306
|
+
if (isCurrent) {
|
|
307
|
+
thumbnail.classList.add('current');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Build DOM safely to prevent XSS from user-supplied variation names
|
|
311
|
+
const previewDiv = document.createElement('div');
|
|
312
|
+
previewDiv.className = 'thumbnail-preview';
|
|
313
|
+
const numberDiv = document.createElement('div');
|
|
314
|
+
numberDiv.className = 'variation-number';
|
|
315
|
+
numberDiv.textContent = index + 1;
|
|
316
|
+
const placeholderDiv = document.createElement('div');
|
|
317
|
+
placeholderDiv.className = 'preview-placeholder';
|
|
318
|
+
previewDiv.appendChild(numberDiv);
|
|
319
|
+
previewDiv.appendChild(placeholderDiv);
|
|
320
|
+
|
|
321
|
+
const infoDiv = document.createElement('div');
|
|
322
|
+
infoDiv.className = 'thumbnail-info';
|
|
323
|
+
const nameDiv = document.createElement('div');
|
|
324
|
+
nameDiv.className = 'variation-name';
|
|
325
|
+
nameDiv.textContent = name;
|
|
326
|
+
const typeDiv = document.createElement('div');
|
|
327
|
+
typeDiv.className = 'variation-type';
|
|
328
|
+
typeDiv.textContent = isDefault ? 'Default' : 'Custom';
|
|
329
|
+
infoDiv.appendChild(nameDiv);
|
|
330
|
+
infoDiv.appendChild(typeDiv);
|
|
331
|
+
|
|
332
|
+
thumbnail.appendChild(previewDiv);
|
|
333
|
+
thumbnail.appendChild(infoDiv);
|
|
334
|
+
|
|
335
|
+
// Event handlers
|
|
336
|
+
thumbnail.addEventListener('mouseenter', () => {
|
|
337
|
+
this.showPreview(index);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
thumbnail.addEventListener('mouseleave', () => {
|
|
341
|
+
this.clearPreview();
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
thumbnail.addEventListener('click', () => {
|
|
345
|
+
this.selectVariation(index);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
return thumbnail;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Show preview for variation
|
|
353
|
+
*/
|
|
354
|
+
showPreview(index) {
|
|
355
|
+
this.currentPreview = index;
|
|
356
|
+
|
|
357
|
+
// Clear existing timeout
|
|
358
|
+
if (this.previewTimeout) {
|
|
359
|
+
clearTimeout(this.previewTimeout);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Delay preview to avoid rapid changes
|
|
363
|
+
this.previewTimeout = setTimeout(() => {
|
|
364
|
+
if (this.currentPreview === index) {
|
|
365
|
+
const params = this.getVariationParameters(index);
|
|
366
|
+
this.previewVisualizer.updateParams(params);
|
|
367
|
+
|
|
368
|
+
// Update preview info
|
|
369
|
+
const title = this.galleryModal.querySelector('.preview-title');
|
|
370
|
+
const details = this.galleryModal.querySelector('.preview-details');
|
|
371
|
+
|
|
372
|
+
title.textContent = this.engine.variationManager.getVariationName(index);
|
|
373
|
+
// Build preview details safely (avoid innerHTML with dynamic data)
|
|
374
|
+
details.textContent = '';
|
|
375
|
+
const lines = [
|
|
376
|
+
`Variation #${index + 1}`,
|
|
377
|
+
`Geometry: ${this.getGeometryName(params.geometry)}`,
|
|
378
|
+
`Density: ${params.gridDensity.toFixed(1)}`,
|
|
379
|
+
`Hue: ${params.hue}\u00B0`
|
|
380
|
+
];
|
|
381
|
+
lines.forEach(text => {
|
|
382
|
+
const div = document.createElement('div');
|
|
383
|
+
div.textContent = text;
|
|
384
|
+
details.appendChild(div);
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}, 100);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Clear preview
|
|
392
|
+
*/
|
|
393
|
+
clearPreview() {
|
|
394
|
+
this.currentPreview = -1;
|
|
395
|
+
|
|
396
|
+
if (this.previewTimeout) {
|
|
397
|
+
clearTimeout(this.previewTimeout);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const title = this.galleryModal.querySelector('.preview-title');
|
|
401
|
+
const details = this.galleryModal.querySelector('.preview-details');
|
|
402
|
+
|
|
403
|
+
title.textContent = 'Hover to preview';
|
|
404
|
+
details.innerHTML = '';
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Select variation and close gallery
|
|
409
|
+
*/
|
|
410
|
+
selectVariation(index) {
|
|
411
|
+
this.engine.setVariation(index);
|
|
412
|
+
this.closeGallery();
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Navigate preview with keyboard
|
|
417
|
+
*/
|
|
418
|
+
navigatePreview(direction) {
|
|
419
|
+
let newIndex = this.currentPreview + direction;
|
|
420
|
+
|
|
421
|
+
// Find next valid variation
|
|
422
|
+
while (newIndex >= 0 && newIndex < 100) {
|
|
423
|
+
if (newIndex < 30 || this.engine.variationManager.customVariations[newIndex - 30] !== null) {
|
|
424
|
+
this.showPreview(newIndex);
|
|
425
|
+
|
|
426
|
+
// Scroll to thumbnail
|
|
427
|
+
const thumbnail = this.galleryModal.querySelector(`[data-variation="${newIndex}"]`);
|
|
428
|
+
if (thumbnail) {
|
|
429
|
+
thumbnail.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
430
|
+
}
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
newIndex += direction;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Get parameters for specific variation
|
|
439
|
+
*/
|
|
440
|
+
getVariationParameters(index) {
|
|
441
|
+
if (index < 30) {
|
|
442
|
+
return this.engine.variationManager.generateDefaultVariation(index);
|
|
443
|
+
} else {
|
|
444
|
+
const customVar = this.engine.variationManager.customVariations[index - 30];
|
|
445
|
+
return customVar ? customVar.parameters : this.engine.parameterManager.getAllParameters();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Get geometry name by index
|
|
451
|
+
*/
|
|
452
|
+
getGeometryName(index) {
|
|
453
|
+
const names = ['Tetrahedron', 'Hypercube', 'Sphere', 'Torus', 'Klein Bottle', 'Fractal', 'Wave', 'Crystal'];
|
|
454
|
+
return names[index] || 'Unknown';
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Update gallery statistics
|
|
459
|
+
*/
|
|
460
|
+
updateGalleryStats() {
|
|
461
|
+
const stats = this.engine.variationManager.getStatistics();
|
|
462
|
+
|
|
463
|
+
document.getElementById('totalVariationsCount').textContent = stats.totalVariations;
|
|
464
|
+
document.getElementById('customVariationsCount').textContent = stats.customVariations;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Toggle preview system
|
|
469
|
+
*/
|
|
470
|
+
togglePreview() {
|
|
471
|
+
const previewContainer = this.galleryModal.querySelector('.preview-container');
|
|
472
|
+
previewContainer.classList.toggle('hidden');
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Export all variations as ZIP
|
|
477
|
+
*/
|
|
478
|
+
exportAllVariations() {
|
|
479
|
+
this.engine.statusManager.info('Exporting all variations...');
|
|
480
|
+
|
|
481
|
+
// This would typically create a ZIP file with all variation configs
|
|
482
|
+
// For now, export custom variations
|
|
483
|
+
this.engine.variationManager.exportCustomVariations();
|
|
484
|
+
}
|
|
485
|
+
}
|