|
@@ -0,0 +1,599 @@
|
|
|
+<!DOCTYPE html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
+ <title>NOVA AI 中枢</title>
|
|
|
+ <style>
|
|
|
+ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700&family=Roboto:wght@400;500&display=swap');
|
|
|
+
|
|
|
+ :root {
|
|
|
+ --bg-dark: #0A0F1E;
|
|
|
+ --neon-blue: #02A9F7;
|
|
|
+ --neon-light: #89D6FB;
|
|
|
+ --metal-gray: #525F7F;
|
|
|
+ --electric-purple: #8A2BE2;
|
|
|
+ --glass-white: rgba(255, 255, 255, 0.15);
|
|
|
+ }
|
|
|
+
|
|
|
+ * {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ body {
|
|
|
+ background-color: var(--bg-dark);
|
|
|
+ color: white;
|
|
|
+ font-family: 'Roboto', sans-serif;
|
|
|
+ height: 100vh;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 顶部状态栏 */
|
|
|
+ .status-bar {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px 24px;
|
|
|
+ background: linear-gradient(to bottom, rgba(10, 15, 30, 0.9), rgba(10, 15, 30, 0.7));
|
|
|
+ backdrop-filter: blur(5px);
|
|
|
+ border-bottom: 1px solid var(--metal-gray);
|
|
|
+ z-index: 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-icons {
|
|
|
+ display: flex;
|
|
|
+ gap: 16px;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-icon {
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ background-color: var(--neon-blue);
|
|
|
+ border-radius: 50%;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-icon::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: -2px;
|
|
|
+ left: -2px;
|
|
|
+ right: -2px;
|
|
|
+ bottom: -2px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 1px solid var(--neon-light);
|
|
|
+ animation: pulse 2s infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ .time {
|
|
|
+ font-family: 'Montserrat', sans-serif;
|
|
|
+ font-weight: bold;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-avatar {
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: linear-gradient(135deg, var(--electric-purple), var(--neon-blue));
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-avatar::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ height: 3px;
|
|
|
+ background: var(--neon-blue);
|
|
|
+ animation: loading 8s linear infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 中央AI核心区 */
|
|
|
+ .ai-core {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: relative;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .energy-ball-container {
|
|
|
+ position: relative;
|
|
|
+ width: 200px;
|
|
|
+ height: 200px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .energy-ball {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: radial-gradient(circle at 30% 30%, var(--neon-blue), transparent 70%);
|
|
|
+ box-shadow: 0 0 30px var(--neon-blue),
|
|
|
+ inset 0 0 20px rgba(2, 169, 247, 0.5);
|
|
|
+ position: relative;
|
|
|
+ animation: float 6s ease-in-out infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ .energy-ball::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: -10px;
|
|
|
+ left: -10px;
|
|
|
+ right: -10px;
|
|
|
+ bottom: -10px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: linear-gradient(45deg, var(--neon-blue), var(--electric-purple), var(--neon-blue));
|
|
|
+ z-index: -1;
|
|
|
+ opacity: 0.7;
|
|
|
+ filter: blur(20px);
|
|
|
+ animation: rotate 20s linear infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ .particles {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 50%;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .particle {
|
|
|
+ position: absolute;
|
|
|
+ background-color: var(--neon-light);
|
|
|
+ border-radius: 50%;
|
|
|
+ opacity: 0.7;
|
|
|
+ animation: particle-float 4s infinite ease-in-out;
|
|
|
+ }
|
|
|
+
|
|
|
+ .greeting {
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .greeting h2 {
|
|
|
+ font-family: 'Montserrat', sans-serif;
|
|
|
+ font-size: 24px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ background: linear-gradient(to right, var(--neon-blue), var(--neon-light));
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+ animation: text-glow 2s infinite alternate;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-wave {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 4px;
|
|
|
+ height: 30px;
|
|
|
+ margin-top: 15px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .wave-bar {
|
|
|
+ width: 4px;
|
|
|
+ height: 10px;
|
|
|
+ background-color: var(--neon-blue);
|
|
|
+ border-radius: 2px;
|
|
|
+ animation: wave 1.2s infinite ease-in-out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 底部快捷区 - 修改为固定定位并向上移动 */
|
|
|
+ .quick-access {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 20px; /* 控制离底部距离 */
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 30px;
|
|
|
+ padding: 15px 20px;
|
|
|
+ background: rgba(10, 15, 30, 0.7);
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+ border-top: 1px solid var(--metal-gray);
|
|
|
+ z-index: 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon {
|
|
|
+ width: 50px;
|
|
|
+ height: 50px;
|
|
|
+ border-radius: 12px;
|
|
|
+ background-color: var(--glass-white);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: move;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon:hover {
|
|
|
+ transform: translateY(-5px);
|
|
|
+ background-color: rgba(2, 169, 247, 0.2);
|
|
|
+ box-shadow: 0 5px 15px rgba(2, 169, 247, 0.3);
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon::after {
|
|
|
+ content: attr(data-app);
|
|
|
+ position: absolute;
|
|
|
+ bottom: -25px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ font-size: 12px;
|
|
|
+ opacity: 0;
|
|
|
+ transition: opacity 0.3s;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon:hover::after {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon i {
|
|
|
+ font-size: 24px;
|
|
|
+ background: linear-gradient(to bottom, var(--neon-light), white);
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 右侧语音输入区 - 修改位置向上移动 */
|
|
|
+ .voice-input {
|
|
|
+ position: fixed;
|
|
|
+ right: 30px;
|
|
|
+ bottom: 150px; /* 调整这个值控制离底部距离 */
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-end;
|
|
|
+ gap: 10px;
|
|
|
+ z-index: 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn {
|
|
|
+ width: 60px;
|
|
|
+ height: 60px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: linear-gradient(135deg, var(--neon-blue), var(--electric-purple));
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: pointer;
|
|
|
+ box-shadow: 0 5px 25px rgba(2, 169, 247, 0.5);
|
|
|
+ transition: all 0.3s;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn:hover {
|
|
|
+ transform: scale(1.1);
|
|
|
+ box-shadow: 0 8px 30px rgba(2, 169, 247, 0.7);
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: -5px;
|
|
|
+ left: -5px;
|
|
|
+ right: -5px;
|
|
|
+ bottom: -5px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 2px solid var(--neon-blue);
|
|
|
+ animation: ripple 2s infinite;
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn.active::before {
|
|
|
+ animation: ripple-active 1s infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn i {
|
|
|
+ font-size: 24px;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .history-bubble {
|
|
|
+ background: var(--glass-white);
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+ padding: 10px 15px;
|
|
|
+ border-radius: 20px;
|
|
|
+ max-width: 200px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(10px);
|
|
|
+ transition: all 0.3s;
|
|
|
+ font-size: 14px;
|
|
|
+ border: 1px solid var(--metal-gray);
|
|
|
+ }
|
|
|
+
|
|
|
+ .history-bubble.show {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 动画 */
|
|
|
+ @keyframes float {
|
|
|
+ 0%, 100% { transform: translateY(0) rotate(0deg); }
|
|
|
+ 50% { transform: translateY(-20px) rotate(2deg); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes rotate {
|
|
|
+ 0% { transform: rotate(0deg); }
|
|
|
+ 100% { transform: rotate(360deg); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes particle-float {
|
|
|
+ 0%, 100% { transform: translate(0, 0); }
|
|
|
+ 25% { transform: translate(5px, 5px); }
|
|
|
+ 50% { transform: translate(-5px, 5px); }
|
|
|
+ 75% { transform: translate(-5px, -5px); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes pulse {
|
|
|
+ 0% { opacity: 0.5; transform: scale(1); }
|
|
|
+ 50% { opacity: 1; transform: scale(1.1); }
|
|
|
+ 100% { opacity: 0.5; transform: scale(1); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes loading {
|
|
|
+ 0% { width: 0; }
|
|
|
+ 100% { width: 100%; }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes wave {
|
|
|
+ 0%, 100% { height: 10px; }
|
|
|
+ 50% { height: 25px; }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes text-glow {
|
|
|
+ 0% { text-shadow: 0 0 5px var(--neon-blue); }
|
|
|
+ 100% { text-shadow: 0 0 15px var(--neon-blue); }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes ripple {
|
|
|
+ 0% { transform: scale(1); opacity: 1; }
|
|
|
+ 100% { transform: scale(1.5); opacity: 0; }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes ripple-active {
|
|
|
+ 0% { transform: scale(1); opacity: 0.7; }
|
|
|
+ 100% { transform: scale(1.8); opacity: 0; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 响应式调整 */
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ .quick-access {
|
|
|
+ gap: 15px;
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .app-icon {
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-input {
|
|
|
+ right: 15px;
|
|
|
+ bottom: 120px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .voice-btn {
|
|
|
+ width: 50px;
|
|
|
+ height: 50px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+ <!-- 顶部状态栏 -->
|
|
|
+ <div class="status-bar">
|
|
|
+ <div class="status-icons">
|
|
|
+ <div class="status-icon"></div>
|
|
|
+ <div class="status-icon"></div>
|
|
|
+ <div class="status-icon"></div>
|
|
|
+ </div>
|
|
|
+ <div class="time">18:24</div>
|
|
|
+ <div class="user-avatar">
|
|
|
+ <i class="fas fa-user"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 中央AI核心区 -->
|
|
|
+ <div class="ai-core">
|
|
|
+ <div class="energy-ball-container">
|
|
|
+ <div class="energy-ball">
|
|
|
+ <div class="particles" id="particles"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="greeting">
|
|
|
+ <h2>HELLO, I'M NOVA</h2>
|
|
|
+ <div class="voice-wave">
|
|
|
+ <div class="wave-bar" style="animation-delay: 0s"></div>
|
|
|
+ <div class="wave-bar" style="animation-delay: 0.2s"></div>
|
|
|
+ <div class="wave-bar" style="animation-delay: 0.4s"></div>
|
|
|
+ <div class="wave-bar" style="animation-delay: 0.6s"></div>
|
|
|
+ <div class="wave-bar" style="animation-delay: 0.8s"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 底部快捷区 -->
|
|
|
+ <div class="quick-access">
|
|
|
+ <div class="app-icon" data-app="微信" draggable="true">
|
|
|
+ <i class="fab fa-weixin"></i>
|
|
|
+ </div>
|
|
|
+ <div class="app-icon" data-app="QQ" draggable="true">
|
|
|
+ <i class="fab fa-qq"></i>
|
|
|
+ </div>
|
|
|
+ <div class="app-icon" data-app="浏览器" draggable="true">
|
|
|
+ <i class="fas fa-globe"></i>
|
|
|
+ </div>
|
|
|
+ <div class="app-icon" data-app="系统管理" draggable="true">
|
|
|
+ <i class="fas fa-cog"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧语音输入区 -->
|
|
|
+ <div class="voice-input">
|
|
|
+ <div class="history-bubble">上次查询: 今天的天气</div>
|
|
|
+ <div class="voice-btn">
|
|
|
+ <i class="fas fa-microphone"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ // 创建粒子效果
|
|
|
+ function createParticles() {
|
|
|
+ const container = document.getElementById('particles');
|
|
|
+ const particleCount = 30;
|
|
|
+
|
|
|
+ for (let i = 0; i < particleCount; i++) {
|
|
|
+ const particle = document.createElement('div');
|
|
|
+ particle.classList.add('particle');
|
|
|
+
|
|
|
+ // 随机大小和位置
|
|
|
+ const size = Math.random() * 4 + 2;
|
|
|
+ const posX = Math.random() * 100;
|
|
|
+ const posY = Math.random() * 100;
|
|
|
+ const delay = Math.random() * 4;
|
|
|
+
|
|
|
+ particle.style.width = `${size}px`;
|
|
|
+ particle.style.height = `${size}px`;
|
|
|
+ particle.style.left = `${posX}%`;
|
|
|
+ particle.style.top = `${posY}%`;
|
|
|
+ particle.style.animationDelay = `${delay}s`;
|
|
|
+
|
|
|
+ container.appendChild(particle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 语音按钮交互
|
|
|
+ function setupVoiceButton() {
|
|
|
+ const voiceBtn = document.querySelector('.voice-btn');
|
|
|
+ const historyBubble = document.querySelector('.history-bubble');
|
|
|
+ const waveBars = document.querySelectorAll('.wave-bar');
|
|
|
+
|
|
|
+ voiceBtn.addEventListener('click', function() {
|
|
|
+ this.classList.toggle('active');
|
|
|
+
|
|
|
+ if (this.classList.contains('active')) {
|
|
|
+ // 模拟语音激活状态
|
|
|
+ waveBars.forEach(bar => {
|
|
|
+ bar.style.animationDuration = '0.8s';
|
|
|
+ });
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ historyBubble.classList.add('show');
|
|
|
+ historyBubble.textContent = '正在聆听...';
|
|
|
+ }, 300);
|
|
|
+ } else {
|
|
|
+ // 模拟语音关闭状态
|
|
|
+ waveBars.forEach(bar => {
|
|
|
+ bar.style.animationDuration = '1.2s';
|
|
|
+ });
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ historyBubble.textContent = '已识别: 打开天气预报';
|
|
|
+ setTimeout(() => {
|
|
|
+ historyBubble.classList.remove('show');
|
|
|
+ }, 2000);
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 拖拽排序功能
|
|
|
+ function setupDragAndDrop() {
|
|
|
+ const quickAccess = document.querySelector('.quick-access');
|
|
|
+ const appIcons = document.querySelectorAll('.app-icon');
|
|
|
+ let draggedItem = null;
|
|
|
+
|
|
|
+ appIcons.forEach(icon => {
|
|
|
+ icon.addEventListener('dragstart', function() {
|
|
|
+ draggedItem = this;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.style.opacity = '0.4';
|
|
|
+ }, 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ icon.addEventListener('dragend', function() {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.style.opacity = '1';
|
|
|
+ draggedItem = null;
|
|
|
+ }, 0);
|
|
|
+ });
|
|
|
+
|
|
|
+ icon.addEventListener('dragover', function(e) {
|
|
|
+ e.preventDefault();
|
|
|
+ });
|
|
|
+
|
|
|
+ icon.addEventListener('dragenter', function(e) {
|
|
|
+ e.preventDefault();
|
|
|
+ this.style.backgroundColor = 'rgba(2, 169, 247, 0.3)';
|
|
|
+ });
|
|
|
+
|
|
|
+ icon.addEventListener('dragleave', function() {
|
|
|
+ this.style.backgroundColor = 'var(--glass-white)';
|
|
|
+ });
|
|
|
+
|
|
|
+ icon.addEventListener('drop', function() {
|
|
|
+ this.style.backgroundColor = 'var(--glass-white)';
|
|
|
+ if (draggedItem !== this) {
|
|
|
+ quickAccess.insertBefore(draggedItem, this.nextSibling || this);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新时间
|
|
|
+ function updateTime() {
|
|
|
+ const timeElement = document.querySelector('.time');
|
|
|
+ const now = new Date();
|
|
|
+ const hours = now.getHours().toString().padStart(2, '0');
|
|
|
+ const minutes = now.getMinutes().toString().padStart(2, '0');
|
|
|
+ timeElement.textContent = `${hours}:${minutes}`;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化
|
|
|
+ document.addEventListener('DOMContentLoaded', function() {
|
|
|
+ createParticles();
|
|
|
+ setupVoiceButton();
|
|
|
+ setupDragAndDrop();
|
|
|
+ updateTime();
|
|
|
+ setInterval(updateTime, 60000);
|
|
|
+
|
|
|
+ // 3D球体悬停效果
|
|
|
+ const energyBall = document.querySelector('.energy-ball');
|
|
|
+ energyBall.addEventListener('mousemove', (e) => {
|
|
|
+ const rect = energyBall.getBoundingClientRect();
|
|
|
+ const x = e.clientX - rect.left;
|
|
|
+ const y = e.clientY - rect.top;
|
|
|
+ const centerX = rect.width / 2;
|
|
|
+ const centerY = rect.height / 2;
|
|
|
+ const angleX = (y - centerY) / 20;
|
|
|
+ const angleY = (centerX - x) / 20;
|
|
|
+
|
|
|
+ energyBall.style.transform = `rotateX(${angleX}deg) rotateY(${angleY}deg)`;
|
|
|
+ });
|
|
|
+
|
|
|
+ energyBall.addEventListener('mouseleave', () => {
|
|
|
+ energyBall.style.transform = '';
|
|
|
+ });
|
|
|
+ });
|
|
|
+ </script>
|
|
|
+</body>
|
|
|
+</html>
|