145 lines
4.9 KiB
HTML
Executable File
145 lines
4.9 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Enhanced AI Voice Assistant Ball</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: #00003300;
|
|
overflow: hidden;
|
|
}
|
|
.ai-ball {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle at 30% 30%, #ff00ff, #00ffff);
|
|
position: relative;
|
|
overflow: hidden;
|
|
box-shadow: 0 0 30px rgba(255, 255, 255, 0.3);
|
|
animation: breathe 4s infinite ease-in-out;
|
|
transition: transform 0.5s ease, animation-duration 0.5s ease, background 0.5s ease;
|
|
}
|
|
@keyframes breathe {
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(1.1); }
|
|
}
|
|
.wave {
|
|
position: absolute;
|
|
width: 400%;
|
|
height: 400%;
|
|
top: -150%;
|
|
left: -150%;
|
|
background: radial-gradient(ellipse at center, transparent 30%, rgba(255, 255, 255, 0.2) 70%);
|
|
animation: wave 16s infinite linear;
|
|
}
|
|
@keyframes wave {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
.glow {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: radial-gradient(circle at center, rgba(255, 255, 255, 0.8) 0%, transparent 70%);
|
|
opacity: 0;
|
|
animation: pulse 2s infinite alternate;
|
|
transition: opacity 0.5s ease;
|
|
}
|
|
@keyframes pulse {
|
|
0% { opacity: 0.2; transform: scale(0.8); }
|
|
100% { opacity: 0.6; transform: scale(1.2); }
|
|
}
|
|
.color-shift {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: radial-gradient(circle at 30% 30%, #ff00ff, #00ffff);
|
|
mix-blend-mode: color;
|
|
animation: colorShift 8s infinite alternate;
|
|
}
|
|
@keyframes colorShift {
|
|
0% { filter: hue-rotate(0deg); }
|
|
100% { filter: hue-rotate(15deg); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="ai-ball">
|
|
<div class="wave"></div>
|
|
<div class="glow"></div>
|
|
<div class="color-shift"></div>
|
|
</div>
|
|
|
|
<script>
|
|
const aiBall = document.querySelector('.ai-ball');
|
|
let audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
let analyser = audioContext.createAnalyser();
|
|
let microphone;
|
|
|
|
navigator.mediaDevices.getUserMedia({ audio: true })
|
|
.then(stream => {
|
|
microphone = audioContext.createMediaStreamSource(stream);
|
|
microphone.connect(analyser);
|
|
analyser.fftSize = 256;
|
|
loop();
|
|
})
|
|
.catch(err => console.error("Access to microphone denied:", err));
|
|
|
|
function loop() {
|
|
window.requestAnimationFrame(loop);
|
|
let dataArray = new Uint8Array(analyser.frequencyBinCount);
|
|
analyser.getByteFrequencyData(dataArray);
|
|
|
|
let sum = dataArray.reduce((a, b) => a + b, 0);
|
|
let average = sum / dataArray.length;
|
|
let volume = average / 128.0;
|
|
|
|
adjustAnimation(volume);
|
|
adjustColor(volume);
|
|
}
|
|
|
|
// function loop() {
|
|
// const now = Date.now();
|
|
// if (now - lastUpdateTime > updateInterval) {
|
|
// lastUpdateTime = now;
|
|
// let dataArray = new Uint8Array(analyser.frequencyBinCount);
|
|
// analyser.getByteFrequencyData(dataArray);
|
|
|
|
// let sum = dataArray.reduce((a, b) => a + b, 0);
|
|
// let average = sum / dataArray.length;
|
|
// let volume = average / 128.0;
|
|
|
|
// adjustAnimation(volume);
|
|
// adjustColor(volume);
|
|
// }
|
|
// window.requestAnimationFrame(loop);
|
|
// }
|
|
|
|
function adjustAnimation(volume) {
|
|
let scale = 1 + volume * 0.5; // Increase scale range
|
|
let speed = 2 - Math.min(0.5, volume * 0.5); // Increase speed sensitivity
|
|
let opacity = 0.2 + volume * 0.5; // Adjust glow opacity based on volume
|
|
|
|
aiBall.style.transform = `scale(${scale})`;
|
|
aiBall.style.animationDuration = `${speed}s`;
|
|
|
|
let glow = aiBall.querySelector('.glow');
|
|
if (glow) {
|
|
glow.style.opacity = opacity;
|
|
}
|
|
}
|
|
|
|
function adjustColor(volume) {
|
|
let hueRotation = volume * -15; // Full hue rotation based on max volume
|
|
aiBall.style.filter = `hue-rotate(${hueRotation}deg)`;
|
|
}
|
|
|
|
</script>
|
|
</body>
|
|
</html> |