Russell Gomersall commited on
Commit
ac3f654
·
1 Parent(s): d7d5644

Update space

Browse files
Files changed (2) hide show
  1. main.js +110 -0
  2. style.css +21 -23
main.js ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // main.js
2
+ import * as THREE from "https://unpkg.com/three@0.164.0/build/three.module.js";
3
+ import { VRButton } from "https://unpkg.com/three@0.164.0/examples/jsm/webxr/VRButton.js";
4
+
5
+ // ----- 1. Basic setup -----
6
+ const scene = new THREE.Scene();
7
+ scene.background = new THREE.Color(0x000000);
8
+
9
+ const camera = new THREE.PerspectiveCamera(
10
+ 70,
11
+ window.innerWidth / window.innerHeight,
12
+ 0.1,
13
+ 1000
14
+ );
15
+ camera.position.set(0, 1.6, 3); // typical VR eye height
16
+
17
+ const renderer = new THREE.WebGLRenderer({ antialias: true });
18
+ renderer.setSize(window.innerWidth, window.innerHeight);
19
+ renderer.xr.enabled = true;
20
+ document.body.appendChild(renderer.domElement);
21
+
22
+ // Add VR button
23
+ document.body.appendChild(VRButton.createButton(renderer));
24
+
25
+ // Simple light setup
26
+ const light = new THREE.DirectionalLight(0xffffff, 0.8);
27
+ light.position.set(5, 10, 7);
28
+ scene.add(light);
29
+
30
+ const ambient = new THREE.AmbientLight(0xffffff, 0.3);
31
+ scene.add(ambient);
32
+
33
+ // ----- 2. Sample graph data (replace with Neo4j later) -----
34
+ // Minimal example: 6 nodes, some edges
35
+ const graphData = {
36
+ nodes: [
37
+ { id: "A", label: "Node A" },
38
+ { id: "B", label: "Node B" },
39
+ { id: "C", label: "Node C" },
40
+ { id: "D", label: "Node D" },
41
+ { id: "E", label: "Node E" },
42
+ { id: "F", label: "Node F" }
43
+ ],
44
+ edges: [
45
+ { source: "A", target: "B" },
46
+ { source: "A", target: "C" },
47
+ { source: "B", target: "D" },
48
+ { source: "C", target: "D" },
49
+ { source: "C", target: "E" },
50
+ { source: "E", target: "F" }
51
+ ]
52
+ };
53
+
54
+ // ----- 3. Layout: place nodes around a circle -----
55
+ const nodeMap = new Map(); // id -> mesh
56
+
57
+ const radius = 2;
58
+ const nodeGeometry = new THREE.SphereGeometry(0.08, 16, 16);
59
+ const nodeMaterial = new THREE.MeshStandardMaterial({ color: 0x00bcd4 });
60
+
61
+ graphData.nodes.forEach((node, index) => {
62
+ const angle = (index / graphData.nodes.length) * Math.PI * 2;
63
+ const x = radius * Math.cos(angle);
64
+ const z = radius * Math.sin(angle);
65
+ const y = 0;
66
+
67
+ const mesh = new THREE.Mesh(nodeGeometry, nodeMaterial.clone());
68
+ mesh.position.set(x, y, z);
69
+ mesh.userData = { id: node.id, label: node.label };
70
+ scene.add(mesh);
71
+
72
+ nodeMap.set(node.id, mesh);
73
+ });
74
+
75
+ // ----- 4. Draw edges as lines between node positions -----
76
+ const edgeMaterial = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 1 });
77
+
78
+ graphData.edges.forEach((edge) => {
79
+ const sourceMesh = nodeMap.get(edge.source);
80
+ const targetMesh = nodeMap.get(edge.target);
81
+ if (!sourceMesh || !targetMesh) return;
82
+
83
+ const points = [];
84
+ points.push(sourceMesh.position.clone());
85
+ points.push(targetMesh.position.clone());
86
+
87
+ const edgeGeometry = new THREE.BufferGeometry().setFromPoints(points);
88
+ const line = new THREE.Line(edgeGeometry, edgeMaterial);
89
+ scene.add(line);
90
+ });
91
+
92
+ // ----- 5. Subtle animation for visual interest -----
93
+ function animate() {
94
+ renderer.setAnimationLoop(renderScene);
95
+ }
96
+
97
+ function renderScene() {
98
+ // Slowly rotate the whole graph
99
+ scene.rotation.y += 0.0015;
100
+ renderer.render(scene, camera);
101
+ }
102
+
103
+ animate();
104
+
105
+ // ----- 6. Handle resize -----
106
+ window.addEventListener("resize", () => {
107
+ camera.aspect = window.innerWidth / window.innerHeight;
108
+ camera.updateProjectionMatrix();
109
+ renderer.setSize(window.innerWidth, window.innerHeight);
110
+ });
style.css CHANGED
@@ -1,28 +1,26 @@
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
 
 
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }
 
1
+ html,
2
  body {
3
+ margin: 0;
4
+ padding: 0;
5
+ overflow: hidden;
6
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
7
+ background: #000;
8
+ color: #fff;
9
  }
10
 
11
+ #overlay {
12
+ position: absolute;
13
+ top: 10px;
14
+ left: 10px;
15
+ z-index: 10;
16
+ background: rgba(0, 0, 0, 0.5);
17
+ padding: 8px 12px;
18
+ border-radius: 8px;
19
+ max-width: 320px;
20
+ font-size: 0.9rem;
21
  }
22
 
23
+ #overlay h1 {
24
+ margin: 0 0 4px 0;
25
+ font-size: 1.1rem;
26
+ }