Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 2. Three.js Visualizer (app.js)
- JavaScript
- let scene, camera, renderer, orbLayers = [], currentState = 'idle';
- let targetScale = 1.0, currentScale = 1.0;
- // Color and State Configurations
- const states = {
- idle: { // Pale and smaller
- layers: [
- { color: 0x2a2e5e, opacity: 0.1, scale: 0.7, rotationSpeed: { x: 0.0005, y: 0.001 } },
- { color: 0x2a2e5e, opacity: 0.1, scale: 0.6, rotationSpeed: { x: -0.001, y: 0.0015 } }
- ],
- timeSpeed: 0.008, pulsate: false, chromaticAberration: 0.2, description: 'Sleeping'
- },
- listening: {
- layers: [
- { color: 0x434FCF, opacity: 0.2, scale: 1.0, rotationSpeed: { x: 0.002, y: 0.004 } },
- { color: 0x434FCF, opacity: 0.4, scale: 0.7, rotationSpeed: { x: 0.004, y: -0.003 } }
- ],
- timeSpeed: 0.022, pulsate: true, pulsateMin: 0.02, pulsateMax: 0.2, chromaticAberration: 1.2, description: 'Listening'
- },
- google: { // Visual bridge: Electric Cyan for High Precision parsing
- layers: [
- { color: 0x00f2ff, opacity: 0.3, scale: 1.1, rotationSpeed: { x: 0.008, y: 0.008 } },
- { color: 0x00f2ff, opacity: 0.5, scale: 0.8, rotationSpeed: { x: -0.01, y: 0.01 } }
- ],
- timeSpeed: 0.05, pulsate: true, pulsateMin: 0.1, pulsateMax: 0.4, chromaticAberration: 2.5, description: 'High Precision'
- },
- thinking: {
- layers: [
- { color: 0x8747F7, opacity: 0.2, scale: 0.85, rotationSpeed: { x: 0.003, y: 0.003 } },
- { color: 0x8747F7, opacity: 0.4, scale: 0.60, rotationSpeed: { x: 0.005, y: -0.004 } }
- ],
- timeSpeed: 0.02, pulsate: true, pulsateMin: 0.0, pulsateMax: 0.15, chromaticAberration: 0.8, description: 'Thinking'
- },
- speaking: {
- layers: [
- { color: 0xFF1893, opacity: 0.2, scale: 1.0, rotationSpeed: { x: 0.004, y: 0.005 } },
- { color: 0xFF1893, opacity: 0.4, scale: 0.70, rotationSpeed: { x: 0.006, y: -0.005 } }
- ],
- timeSpeed: 0.027, pulsate: true, pulsateMin: 0.05, pulsateMax: 0.22, chromaticAberration: 1.5, description: 'Speaking'
- }
- };
- const vertexShader = `
- varying vec3 vNormal;
- varying vec3 vPosition;
- uniform float time;
- uniform float audioLevel;
- void main() {
- vNormal = normalize(normalMatrix * normal);
- vec3 pos = position;
- float distortion = sin(pos.y * 3.0 + time) * 0.02 * (1.0 + audioLevel);
- pos = pos + normal * distortion;
- vPosition = pos;
- gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
- }
- `;
- const fragmentShader = `
- varying vec3 vNormal;
- varying vec3 vPosition;
- uniform vec3 sphereColor;
- uniform float opacity;
- uniform float chromaticAberration;
- void main() {
- vec3 viewDirection = normalize(cameraPosition - vPosition);
- float fresnel = pow(1.0 - abs(dot(viewDirection, normalize(vNormal))), 2.0);
- vec3 color = sphereColor + (fresnel * chromaticAberration * 0.3);
- gl_FragColor = vec4(color, opacity + (fresnel * 0.4));
- }
- `;
- function init() {
- scene = new THREE.Scene();
- camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
- camera.position.z = 5;
- const canvas = document.getElementById('canvas');
- renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
- renderer.setSize(window.innerWidth, window.innerHeight);
- // Create 2 fixed layers to allow smooth transitions
- for (let i = 0; i < 2; i++) {
- const geometry = new THREE.SphereGeometry(1, 64, 64);
- const material = new THREE.ShaderMaterial({
- vertexShader, fragmentShader,
- uniforms: {
- time: { value: 0 }, audioLevel: { value: 0 },
- sphereColor: { value: new THREE.Color(0x000000) },
- opacity: { value: 0 }, chromaticAberration: { value: 0 }
- },
- transparent: true, depthWrite: false
- });
- const sphere = new THREE.Mesh(geometry, material);
- sphere.userData = { currentScale: 0.1, targetScale: 0.1, rot: { x: 0, y: 0 } };
- scene.add(sphere);
- orbLayers.push(sphere);
- }
- window.addEventListener('resize', () => {
- camera.aspect = window.innerWidth / window.innerHeight;
- camera.updateProjectionMatrix();
- renderer.setSize(window.innerWidth, window.innerHeight);
- });
- animate();
- }
- function setState(stateName) {
- if (!states[stateName]) return;
- currentState = stateName;
- const statusEl = document.getElementById('status');
- if (statusEl) {
- statusEl.textContent = states[stateName].description;
- }
- }
- function animate() {
- requestAnimationFrame(animate);
- const state = states[currentState];
- const lerpSpeed = 0.05; // Controls the smoothness of the transition
- orbLayers.forEach((layer, index) => {
- const config = state.layers[index] || { color: 0x000000, opacity: 0, scale: 0, rotationSpeed: { x: 0, y: 0 } };
- const uniforms = layer.material.uniforms;
- // Smooth Color Interpolation
- uniforms.sphereColor.value.lerp(new THREE.Color(config.color), lerpSpeed);
- // Smooth Opacity and Aberration Interpolation
- uniforms.opacity.value += (config.opacity - uniforms.opacity.value) * lerpSpeed;
- uniforms.chromaticAberration.value += (state.chromaticAberration - uniforms.chromaticAberration.value) * lerpSpeed;
- // Smooth Scale Interpolation
- let pulse = state.pulsate ? (Math.sin(Date.now() * 0.005) * (state.pulsateMax - state.pulsateMin)) : 0;
- let tScale = config.scale + pulse;
- layer.scale.setScalar(layer.scale.x + (tScale - layer.scale.x) * lerpSpeed);
- // Animation
- uniforms.time.value += state.timeSpeed;
- layer.rotation.x += config.rotationSpeed.x;
- layer.rotation.y += config.rotationSpeed.y;
- });
- renderer.render(scene, camera);
- }
- function connectToAssistant() {
- const socket = new WebSocket('ws://127.0.0.1:8765');
- socket.onopen = () => {
- const statusEl = document.getElementById('status');
- if (statusEl) statusEl.textContent = 'Assistant Online';
- };
- socket.onmessage = (event) => {
- try {
- const data = JSON.parse(event.data);
- if (data.state) setState(data.state);
- } catch (e) {}
- };
- socket.onclose = () => setTimeout(connectToAssistant, 2000);
- }
- window.addEventListener('DOMContentLoaded', () => {
- init();
- connectToAssistant();
- });
- 3. Visual UI Base (index.html)
- HTML
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Voice Assistant UI - Smooth</title>
- <link rel="stylesheet" href="style.css">
- <style>
- body {
- cursor: none;
- background-color: #000;
- margin: 0;
- overflow: hidden;
- }
- #controls {
- pointer-events: none;
- border: none;
- background: none;
- }
- .state-buttons, #startBtn, .theme-toggle {
- display: none !important;
- }
- #status {
- bottom: 30px;
- opacity: 0.3;
- font-size: 12px;
- letter-spacing: 2px;
- text-transform: uppercase;
- color: white;
- position: fixed;
- width: 100%;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <div id="container">
- <canvas id="canvas"></canvas>
- <div id="controls">
- <div id="status">Connecting...</div>
- </div>
- </div>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
- <script src="app.js"></script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment