下面是最终效果,手指移出指定区域就改为取消状态,松开手指就取消,手指没有移出指定区域,状态为录音中,松开手指为结束录音状态
下面是代码
<!DOCTYPE html> <html lang="zh"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>语音交互样式</title><style>body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #f5f5f5;}.voice-container {position: relative;width: 200px;height: 200px;}/* 语音交互按钮 */.voice-btn {position: absolute;bottom: 20px;left: 50%;transform: translateX(-50%);width: 80px;height: 80px;background-color: #4CAF50;border-radius: 50%;display: flex;justify-content: center;align-items: center;color: white;font-size: 20px;cursor: pointer;transition: background-color 0.3s;}.voice-btn:active {background-color: #388E3C;}/* 正在语音识别的状态 */.voice-recognizing {position: absolute;bottom: 0;left: 50%;transform: translateX(-50%);width: 100%;height: 100px;background-color: rgba(0, 0, 0, 0.2);border-radius: 20px 20px 0 0;display: flex;justify-content: center;align-items: center;color: white;font-size: 16px;display: none; /* 默认隐藏 */transition: background-color 0.3s;}/* 预取消状态:当手指移出语音识别区域时,改变样式 */.voice-recognizing.canceling {background-color: rgba(255, 0, 0, 0.5); /* 改为红色表示预取消 */}/* 取消区域:顶部区域用于取消语音识别 */.cancel-area {position: absolute;top: 0;left: 50%;transform: translateX(-50%);width: 100%;height: 30px;background-color: rgba(255, 0, 0, 0.8); /* 红色背景 */color: white;text-align: center;line-height: 30px;font-size: 14px;display: none; /* 默认隐藏 */cursor: pointer;z-index: 1;}/* 取消区域显示 */.cancel-area.show {display: block;}/* 取消区域 hover 样式 */.cancel-area:hover {background-color: rgba(255, 0, 0, 1);}</style> </head> <body><div class="voice-container"><!-- 语音交互按钮 --><div class="voice-btn" id="voiceBtn">🎤</div><!-- 正在语音识别 --><div class="voice-recognizing" id="voiceRecognizing">正在识别...</div><!-- 取消区域 --><div class="cancel-area" id="cancelArea">松开手指取消语音识别</div></div><script>const voiceBtn = document.getElementById('voiceBtn');const voiceRecognizing = document.getElementById('voiceRecognizing');const cancelArea = document.getElementById('cancelArea');let isRecognizing = false; // 标识当前是否正在识别let isTouching = false; // 标识是否有触摸事件正在进行let touchStartY = 0; // 记录触摸开始的位置let isCanceling = false; // 标识是否进入预取消状态// 按下按钮开始语音识别voiceBtn.addEventListener('mousedown', startRecognition);voiceBtn.addEventListener('touchstart', startRecognition);function startRecognition(e) {e.preventDefault(); // 阻止默认事件,避免页面滚动等isRecognizing = true;voiceRecognizing.style.display = 'flex'; // 显示正在语音识别的状态cancelArea.classList.add('show'); // 显示取消区域isTouching = true;isCanceling = false; // 初始状态不是预取消// 记录触摸开始的位置,用于判断手指滑动方向if (e.type === 'touchstart') {touchStartY = e.touches[0].clientY;}// 禁止页面滚动document.body.style.overflow = 'hidden';}// 松开按钮结束语音识别voiceBtn.addEventListener('mouseup', stopRecognition);voiceBtn.addEventListener('touchend', stopRecognition);function stopRecognition(e) {if (isRecognizing && isCanceling) {// 如果处于预取消状态,取消语音识别 cancelRecognition();} else if (isRecognizing) {// 如果没有进入取消区域,正常结束语音识别 finishRecognition();}isTouching = false;isCanceling = false;// 恢复页面滚动document.body.style.overflow = 'auto';}// 取消语音识别function cancelRecognition() {isRecognizing = false;voiceRecognizing.style.display = 'none'; // 隐藏正在识别状态cancelArea.classList.remove('show'); // 隐藏取消区域voiceRecognizing.classList.remove('canceling'); // 清除预取消状态样式alert('语音识别已取消');}// 完成语音识别function finishRecognition() {isRecognizing = false;voiceRecognizing.style.display = 'none'; // 隐藏正在识别状态cancelArea.classList.remove('show'); // 隐藏取消区域voiceRecognizing.classList.remove('canceling'); // 清除预取消状态样式alert('语音识别结束');}// 在触摸时,检测是否滑动出了 voice-recognizing 区域document.addEventListener('touchmove', handleTouchMove, { passive: false });function handleTouchMove(e) {e.preventDefault(); // 阻止默认的滚动行为if (isTouching) {const touch = e.touches[0];const recognizerRect = voiceRecognizing.getBoundingClientRect();// 判断手指是否离开了 voice-recognizing 区域if (touch.clientY < recognizerRect.top || touch.clientY > recognizerRect.bottom) {// 进入预取消状态if (!isCanceling) {voiceRecognizing.classList.add('canceling'); // 改为红色表示预取消isCanceling = true;}} else {// 手指回到识别区域,取消预取消状态if (isCanceling) {voiceRecognizing.classList.remove('canceling');isCanceling = false;}}}}// 取消区域的点击事件cancelArea.addEventListener('click', cancelRecognition);</script></body> </html>