Files
dss/team-portal/src/js/conscious/Being.js
Digital Production Factory 276ed71f31 Initial commit: Clean DSS implementation
Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm

Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)

Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability

Migration completed: $(date)
🤖 Clean migration with full functionality preserved
2025-12-09 18:45:48 -03:00

202 lines
4.8 KiB
JavaScript

// The Conscious Being - Main Controller
import { Renderer } from './Renderer.js';
import { ParticleSystem } from './ParticleSystem.js';
import { FlockingBehavior, BreathingBehavior, FollowBehavior } from './Behaviors.js';
export class Being {
constructor(canvas) {
this.canvas = canvas;
this.renderer = null;
this.particleSystem = null;
this.behaviors = [];
this.mousePosition = { x: 0.5, y: 0.5 }; // Normalized 0-1
this.target = null;
this.mode = 'idle'; // idle, aware, engaged, background
this.isRunning = false;
this.lastTime = 0;
this.initialized = false;
// Store bound handlers for cleanup
this._resizeHandler = this.handleResize.bind(this);
this.init();
}
init() {
try {
// Initialize renderer with WebGL error handling
this.renderer = new Renderer(this.canvas);
// Initialize particle system
this.particleSystem = new ParticleSystem(800);
// Initialize behaviors
this.behaviors = [
new BreathingBehavior(),
new FlockingBehavior(),
new FollowBehavior()
];
// Add particle system to scene
this.renderer.add(this.particleSystem.mesh);
// Handle resize
window.addEventListener('resize', this._resizeHandler);
this.initialized = true;
} catch (error) {
console.error('[Being] WebGL initialization failed:', error);
this.showFallback();
}
}
showFallback() {
// Show CSS-based fallback animation when WebGL is unavailable
if (this.canvas) {
this.canvas.style.display = 'none';
const fallback = document.createElement('div');
fallback.className = 'conscious-fallback';
fallback.innerHTML = `
<div class="fallback-orb"></div>
<div class="fallback-ring"></div>
<div class="fallback-ring fallback-ring--delayed"></div>
`;
this.canvas.parentNode?.insertBefore(fallback, this.canvas);
}
}
start() {
if (this.isRunning || !this.initialized) return;
this.isRunning = true;
this.lastTime = performance.now();
this.animate();
console.log('[Being] Started');
}
stop() {
this.isRunning = false;
console.log('[Being] Stopped');
}
animate() {
if (!this.isRunning) return;
const currentTime = performance.now();
const deltaTime = (currentTime - this.lastTime) / 1000; // Convert to seconds
this.lastTime = currentTime;
this.update(deltaTime, currentTime);
this.renderer.render();
requestAnimationFrame(() => this.animate());
}
update(deltaTime, time) {
// Apply behaviors based on mode
const params = {
time,
deltaTime,
mousePosition: this.mousePosition,
target: this.target,
mode: this.mode
};
// Apply each behavior
this.behaviors.forEach(behavior => {
behavior.apply(this.particleSystem, params);
});
// Update particle system
this.particleSystem.update(deltaTime);
// Update uniforms
this.particleSystem.material.uniforms.uTime.value = time * 0.001;
this.particleSystem.material.uniforms.uMouse.value.set(
this.mousePosition.x,
this.mousePosition.y
);
}
updateMousePosition(x, y) {
// Normalize to 0-1
this.mousePosition = {
x: x / window.innerWidth,
y: 1 - (y / window.innerHeight) // Flip Y for WebGL
};
// Update mode based on mouse activity
if (this.mode === 'idle') {
this.setMode('aware');
}
}
setTarget(element) {
if (!element) {
this.target = null;
return;
}
const rect = element.getBoundingClientRect();
this.target = {
x: (rect.left + rect.width / 2) / window.innerWidth,
y: 1 - ((rect.top + rect.height / 2) / window.innerHeight),
width: rect.width / window.innerWidth,
height: rect.height / window.innerHeight
};
this.setMode('engaged');
}
clearTarget() {
this.target = null;
if (this.mode === 'engaged') {
this.setMode('aware');
}
}
setMode(mode) {
if (this.mode === mode) return;
const oldMode = this.mode;
this.mode = mode;
console.log(`[Being] Mode: ${oldMode} -> ${mode}`);
// Adjust behaviors based on mode
this.behaviors.forEach(behavior => {
behavior.onModeChange(mode, oldMode);
});
// Adjust particle appearance
if (mode === 'background') {
this.particleSystem.setOpacity(0.3);
} else {
this.particleSystem.setOpacity(1.0);
}
}
handleResize() {
this.renderer.handleResize();
}
dispose() {
this.stop();
// Remove event listeners
window.removeEventListener('resize', this._resizeHandler);
// Dispose of WebGL resources
if (this.renderer) {
this.renderer.dispose();
}
if (this.particleSystem) {
this.particleSystem.dispose();
}
this.initialized = false;
}
}
export default Being;