feat(ui): add floating menu for video selection
Implement floating button that toggles a menu with video options Add styling for floating elements and handle click interactions Update video switching logic to prevent unintended transitions
This commit is contained in:
12
index.html
12
index.html
@@ -43,6 +43,18 @@
|
|||||||
<p id="transcript"></p>
|
<p id="transcript"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 悬浮球 -->
|
||||||
|
<div id="floating-button">
|
||||||
|
<i class="fas fa-bars"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 悬浮菜单 -->
|
||||||
|
<div id="menu-container" class="hidden">
|
||||||
|
<button class="menu-item" data-video="视频资源/jimeng-2025-07-16-4437-比耶,然后微笑着优雅的左右摇晃.mp4">Pose</button>
|
||||||
|
<button class="menu-item" data-video="视频资源/生成加油视频.mp4">Cheer</button>
|
||||||
|
<button class="menu-item" data-video="视频资源/生成跳舞视频.mp4">Dance</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 底部麦克风和链接 -->
|
<!-- 底部麦克风和链接 -->
|
||||||
<footer class="bottom-bar">
|
<footer class="bottom-bar">
|
||||||
<button class="mic-button" id="mic-button" aria-label="Start Listening">
|
<button class="mic-button" id="mic-button" aria-label="Start Listening">
|
||||||
|
|||||||
49
script.js
49
script.js
@@ -15,6 +15,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
let video2 = document.getElementById('video2');
|
let video2 = document.getElementById('video2');
|
||||||
const micButton = document.getElementById('mic-button');
|
const micButton = document.getElementById('mic-button');
|
||||||
const favorabilityBar = document.getElementById('favorability-bar');
|
const favorabilityBar = document.getElementById('favorability-bar');
|
||||||
|
const floatingButton = document.getElementById('floating-button');
|
||||||
|
const menuContainer = document.getElementById('menu-container');
|
||||||
|
const menuItems = document.querySelectorAll('.menu-item');
|
||||||
|
|
||||||
let activeVideo = video1;
|
let activeVideo = video1;
|
||||||
let inactiveVideo = video2;
|
let inactiveVideo = video2;
|
||||||
@@ -134,6 +137,51 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// --- 悬浮按钮交互 ---
|
||||||
|
floatingButton.addEventListener('click', (event) => {
|
||||||
|
event.stopPropagation(); // 防止事件冒泡到 document
|
||||||
|
menuContainer.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
menuItems.forEach(item => {
|
||||||
|
item.addEventListener('click', function() {
|
||||||
|
const videoSrc = this.getAttribute('data-video');
|
||||||
|
playSpecificVideo(videoSrc);
|
||||||
|
menuContainer.classList.add('hidden');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 点击菜单外部区域关闭菜单
|
||||||
|
document.addEventListener('click', () => {
|
||||||
|
if (!menuContainer.classList.contains('hidden')) {
|
||||||
|
menuContainer.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 阻止菜单自身的点击事件冒泡
|
||||||
|
menuContainer.addEventListener('click', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function playSpecificVideo(videoSrc) {
|
||||||
|
const currentVideoSrc = activeVideo.querySelector('source').getAttribute('src');
|
||||||
|
if (videoSrc === currentVideoSrc) return;
|
||||||
|
|
||||||
|
inactiveVideo.querySelector('source').setAttribute('src', videoSrc);
|
||||||
|
inactiveVideo.load();
|
||||||
|
|
||||||
|
inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() {
|
||||||
|
inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough);
|
||||||
|
activeVideo.pause(); // 暂停当前视频,防止其 'ended' 事件触发切换
|
||||||
|
inactiveVideo.play().catch(error => console.error("Video play failed:", error));
|
||||||
|
activeVideo.classList.remove('active');
|
||||||
|
inactiveVideo.classList.add('active');
|
||||||
|
[activeVideo, inactiveVideo] = [inactiveVideo, activeVideo];
|
||||||
|
activeVideo.addEventListener('ended', switchVideo, { once: true });
|
||||||
|
}, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
// --- 情感分析与反应 ---
|
// --- 情感分析与反应 ---
|
||||||
const positiveWords = ['开心', '高兴', '喜欢', '太棒了', '你好', '漂亮'];
|
const positiveWords = ['开心', '高兴', '喜欢', '太棒了', '你好', '漂亮'];
|
||||||
const negativeWords = ['难过', '生气', '讨厌', '伤心'];
|
const negativeWords = ['难过', '生气', '讨厌', '伤心'];
|
||||||
@@ -179,6 +227,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() {
|
inactiveVideo.addEventListener('canplaythrough', function onCanPlayThrough() {
|
||||||
inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough);
|
inactiveVideo.removeEventListener('canplaythrough', onCanPlayThrough);
|
||||||
|
activeVideo.pause(); // 暂停当前视频,防止其 'ended' 事件触发切换
|
||||||
inactiveVideo.play().catch(error => console.error("Video play failed:", error));
|
inactiveVideo.play().catch(error => console.error("Video play failed:", error));
|
||||||
activeVideo.classList.remove('active');
|
activeVideo.classList.remove('active');
|
||||||
inactiveVideo.classList.add('active');
|
inactiveVideo.classList.add('active');
|
||||||
|
|||||||
72
style.css
72
style.css
@@ -152,6 +152,78 @@ html, body {
|
|||||||
text-shadow: 1px 1px 2px rgba(0,0,0,0.7);
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- 悬浮按钮和菜单 --- */
|
||||||
|
#floating-button {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 120px; /* 调整位置,使其在麦克风按钮上方 */
|
||||||
|
right: 30px;
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
#floating-button:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#floating-button i {
|
||||||
|
font-size: 24px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-container {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 200px; /* 调整位置,使其在悬浮按钮上方 */
|
||||||
|
right: 30px;
|
||||||
|
width: 150px;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 9;
|
||||||
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||||
|
transform-origin: bottom right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#menu-container.hidden {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
font-size: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --- 底部内容 --- */
|
/* --- 底部内容 --- */
|
||||||
.bottom-bar {
|
.bottom-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user