watercooler 0.0.6 → 0.0.7
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/package.json +1 -1
- package/public/app.js +168 -5
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
3
|
+
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
|
|
4
|
+
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
|
|
5
|
+
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
|
|
3
6
|
|
|
4
7
|
// State
|
|
5
8
|
let config = { user: '', mailbox: '', avatar: null };
|
|
@@ -36,6 +39,8 @@ let holoSphere = null;
|
|
|
36
39
|
let holoParticles = null;
|
|
37
40
|
let glowLights = [];
|
|
38
41
|
let floatingParticles = [];
|
|
42
|
+
let composer = null;
|
|
43
|
+
let waterMesh = null;
|
|
39
44
|
|
|
40
45
|
// Initialize Three.js
|
|
41
46
|
function init() {
|
|
@@ -99,9 +104,27 @@ function init() {
|
|
|
99
104
|
const hemiLight = new THREE.HemisphereLight(0x4fd1c5, 0x1a3a3a, 0.4);
|
|
100
105
|
scene.add(hemiLight);
|
|
101
106
|
|
|
107
|
+
// Additional accent lights for bloom effect
|
|
108
|
+
// Center glow from holographic sphere area
|
|
109
|
+
const centerGlow = new THREE.PointLight(0x4fd1c5, 0.6, 50);
|
|
110
|
+
centerGlow.position.set(0, PLATFORM_HEIGHT + 15, 0);
|
|
111
|
+
scene.add(centerGlow);
|
|
112
|
+
|
|
113
|
+
// Edge accent lights
|
|
114
|
+
const edgeLight1 = new THREE.PointLight(0x88ffdd, 0.4, 30);
|
|
115
|
+
edgeLight1.position.set(30, PLATFORM_HEIGHT + 10, 30);
|
|
116
|
+
scene.add(edgeLight1);
|
|
117
|
+
|
|
118
|
+
const edgeLight2 = new THREE.PointLight(0x88ffdd, 0.4, 30);
|
|
119
|
+
edgeLight2.position.set(-30, PLATFORM_HEIGHT + 10, -30);
|
|
120
|
+
scene.add(edgeLight2);
|
|
121
|
+
|
|
102
122
|
// === Platform ===
|
|
103
123
|
createPlatform();
|
|
104
124
|
|
|
125
|
+
// === Reflective Water Surface ===
|
|
126
|
+
createReflectiveWater();
|
|
127
|
+
|
|
105
128
|
// === Glass Walls ===
|
|
106
129
|
createGlassWalls();
|
|
107
130
|
|
|
@@ -117,6 +140,9 @@ function init() {
|
|
|
117
140
|
// === Floating Particles ===
|
|
118
141
|
createFloatingParticles();
|
|
119
142
|
|
|
143
|
+
// === Background Stars ===
|
|
144
|
+
createBackgroundStars();
|
|
145
|
+
|
|
120
146
|
window.addEventListener('resize', onWindowResize);
|
|
121
147
|
|
|
122
148
|
// Raycaster for desk clicks
|
|
@@ -136,6 +162,9 @@ function init() {
|
|
|
136
162
|
setTimeout(onWindowResize, 100);
|
|
137
163
|
});
|
|
138
164
|
|
|
165
|
+
// === Post Processing ===
|
|
166
|
+
setupPostProcessing();
|
|
167
|
+
|
|
139
168
|
animate();
|
|
140
169
|
}
|
|
141
170
|
|
|
@@ -198,6 +227,56 @@ function createPlatform() {
|
|
|
198
227
|
scene.add(ground);
|
|
199
228
|
}
|
|
200
229
|
|
|
230
|
+
function createReflectiveWater() {
|
|
231
|
+
// Reflective water surface below the platform
|
|
232
|
+
const waterSize = PLATFORM_SIZE * 1.5;
|
|
233
|
+
const waterGeo = new THREE.PlaneGeometry(waterSize, waterSize, 64, 64);
|
|
234
|
+
|
|
235
|
+
// Create a custom shader material for reflective water effect
|
|
236
|
+
const waterMat = new THREE.MeshPhysicalMaterial({
|
|
237
|
+
color: 0x0d3333,
|
|
238
|
+
metalness: 0.9,
|
|
239
|
+
roughness: 0.1,
|
|
240
|
+
transparent: true,
|
|
241
|
+
opacity: 0.85,
|
|
242
|
+
transmission: 0.3,
|
|
243
|
+
thickness: 0.5,
|
|
244
|
+
clearcoat: 1.0,
|
|
245
|
+
clearcoatRoughness: 0.1,
|
|
246
|
+
side: THREE.DoubleSide
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
waterMesh = new THREE.Mesh(waterGeo, waterMat);
|
|
250
|
+
waterMesh.rotation.x = -Math.PI / 2;
|
|
251
|
+
waterMesh.position.y = -0.5;
|
|
252
|
+
waterMesh.receiveShadow = true;
|
|
253
|
+
scene.add(waterMesh);
|
|
254
|
+
|
|
255
|
+
// Add subtle ripple effect using vertex displacement
|
|
256
|
+
const positions = waterMesh.geometry.attributes.position;
|
|
257
|
+
const initialPositions = positions.array.slice();
|
|
258
|
+
waterMesh.userData.initialPositions = initialPositions;
|
|
259
|
+
waterMesh.userData.ripplePhase = 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function setupPostProcessing() {
|
|
263
|
+
// Setup EffectComposer for bloom
|
|
264
|
+
composer = new EffectComposer(renderer);
|
|
265
|
+
|
|
266
|
+
// Add render pass
|
|
267
|
+
const renderPass = new RenderPass(scene, camera);
|
|
268
|
+
composer.addPass(renderPass);
|
|
269
|
+
|
|
270
|
+
// Add bloom pass
|
|
271
|
+
const bloomPass = new UnrealBloomPass(
|
|
272
|
+
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
|
273
|
+
0.8, // strength
|
|
274
|
+
0.4, // radius
|
|
275
|
+
0.75 // threshold
|
|
276
|
+
);
|
|
277
|
+
composer.addPass(bloomPass);
|
|
278
|
+
}
|
|
279
|
+
|
|
201
280
|
function createGlassWalls() {
|
|
202
281
|
const glassMat = new THREE.MeshPhysicalMaterial({
|
|
203
282
|
color: 0x88cccc,
|
|
@@ -491,6 +570,48 @@ function createFloatingParticles() {
|
|
|
491
570
|
floatingParticles.push(particles);
|
|
492
571
|
}
|
|
493
572
|
|
|
573
|
+
function createBackgroundStars() {
|
|
574
|
+
// Distant stars/sparkles in the background
|
|
575
|
+
const starCount = 200;
|
|
576
|
+
const positions = new Float32Array(starCount * 3);
|
|
577
|
+
const sizes = new Float32Array(starCount);
|
|
578
|
+
|
|
579
|
+
for (let i = 0; i < starCount; i++) {
|
|
580
|
+
// Place stars far outside the platform
|
|
581
|
+
const theta = Math.random() * Math.PI * 2;
|
|
582
|
+
const phi = Math.acos(2 * Math.random() - 1);
|
|
583
|
+
const radius = 100 + Math.random() * 150;
|
|
584
|
+
|
|
585
|
+
positions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);
|
|
586
|
+
positions[i * 3 + 1] = 20 + Math.random() * 100;
|
|
587
|
+
positions[i * 3 + 2] = radius * Math.sin(phi) * Math.sin(theta);
|
|
588
|
+
|
|
589
|
+
sizes[i] = 0.5 + Math.random() * 1.5;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const geometry = new THREE.BufferGeometry();
|
|
593
|
+
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
594
|
+
geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1));
|
|
595
|
+
|
|
596
|
+
const material = new THREE.PointsMaterial({
|
|
597
|
+
color: 0xaaddff,
|
|
598
|
+
size: 1.0,
|
|
599
|
+
transparent: true,
|
|
600
|
+
opacity: 0.6,
|
|
601
|
+
blending: THREE.AdditiveBlending,
|
|
602
|
+
sizeAttenuation: true
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
const stars = new THREE.Points(geometry, material);
|
|
606
|
+
scene.add(stars);
|
|
607
|
+
|
|
608
|
+
// Animate stars with twinkle effect
|
|
609
|
+
stars.userData.twinklePhase = Math.random() * Math.PI * 2;
|
|
610
|
+
|
|
611
|
+
// Add to floatingParticles for animation
|
|
612
|
+
floatingParticles.push(stars);
|
|
613
|
+
}
|
|
614
|
+
|
|
494
615
|
function createAgentDesk(name, position, toolName = null) {
|
|
495
616
|
const color = getAgentColor(name);
|
|
496
617
|
const group = new THREE.Group();
|
|
@@ -946,12 +1067,23 @@ function animate() {
|
|
|
946
1067
|
}
|
|
947
1068
|
|
|
948
1069
|
// Animate floating particles
|
|
949
|
-
floatingParticles.forEach(particles => {
|
|
1070
|
+
floatingParticles.forEach((particles, index) => {
|
|
950
1071
|
const positions = particles.geometry.attributes.position.array;
|
|
951
|
-
|
|
952
|
-
|
|
1072
|
+
|
|
1073
|
+
if (particles.userData.twinklePhase !== undefined) {
|
|
1074
|
+
// Star twinkling effect
|
|
1075
|
+
const twinkle = Math.sin(time * 2 + particles.userData.twinklePhase) * 0.3 + 0.7;
|
|
1076
|
+
particles.material.opacity = 0.4 + twinkle * 0.4;
|
|
1077
|
+
|
|
1078
|
+
// Slowly rotate stars
|
|
1079
|
+
particles.rotation.y = time * 0.02;
|
|
1080
|
+
} else {
|
|
1081
|
+
// Regular floating particles
|
|
1082
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
1083
|
+
positions[i + 1] += Math.sin(time + positions[i] * 0.1) * 0.003;
|
|
1084
|
+
}
|
|
1085
|
+
particles.geometry.attributes.position.needsUpdate = true;
|
|
953
1086
|
}
|
|
954
|
-
particles.geometry.attributes.position.needsUpdate = true;
|
|
955
1087
|
});
|
|
956
1088
|
|
|
957
1089
|
// Subtle glow pulse on lamps
|
|
@@ -960,8 +1092,34 @@ function animate() {
|
|
|
960
1092
|
item.light.intensity = item.baseIntensity * pulse;
|
|
961
1093
|
});
|
|
962
1094
|
|
|
1095
|
+
// Animate water ripples
|
|
1096
|
+
if (waterMesh && waterMesh.userData.initialPositions) {
|
|
1097
|
+
const positions = waterMesh.geometry.attributes.position;
|
|
1098
|
+
const initialPositions = waterMesh.userData.initialPositions;
|
|
1099
|
+
|
|
1100
|
+
for (let i = 0; i < positions.count; i++) {
|
|
1101
|
+
const x = initialPositions[i * 3];
|
|
1102
|
+
const y = initialPositions[i * 3 + 1];
|
|
1103
|
+
|
|
1104
|
+
// Create gentle ripple effect
|
|
1105
|
+
const distance = Math.sqrt(x * x + y * y);
|
|
1106
|
+
const wave1 = Math.sin(distance * 0.3 - time * 0.8) * 0.15;
|
|
1107
|
+
const wave2 = Math.sin(x * 0.2 + time * 0.5) * 0.1;
|
|
1108
|
+
const wave3 = Math.cos(y * 0.15 + time * 0.3) * 0.08;
|
|
1109
|
+
|
|
1110
|
+
positions.setZ(i, wave1 + wave2 + wave3);
|
|
1111
|
+
}
|
|
1112
|
+
positions.needsUpdate = true;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
963
1115
|
controls.update();
|
|
964
|
-
|
|
1116
|
+
|
|
1117
|
+
// Use composer for bloom effect if available, otherwise standard renderer
|
|
1118
|
+
if (composer) {
|
|
1119
|
+
composer.render();
|
|
1120
|
+
} else {
|
|
1121
|
+
renderer.render(scene, camera);
|
|
1122
|
+
}
|
|
965
1123
|
}
|
|
966
1124
|
|
|
967
1125
|
function onWindowResize() {
|
|
@@ -971,6 +1129,11 @@ function onWindowResize() {
|
|
|
971
1129
|
camera.updateProjectionMatrix();
|
|
972
1130
|
renderer.setSize(width, height);
|
|
973
1131
|
|
|
1132
|
+
// Resize composer for bloom effect
|
|
1133
|
+
if (composer) {
|
|
1134
|
+
composer.setSize(width, height);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
974
1137
|
if (width < 768) {
|
|
975
1138
|
camera.position.y = Math.max(camera.position.y, 40);
|
|
976
1139
|
camera.position.z = Math.max(camera.position.z, 50);
|