HTML5视频暂停时鼠标绘图无法显示问题排查求助
问题根源与解决方案
嘿,我立刻发现了你代码里的两个核心问题,这就是Canvas绘图无法显示的原因:
1. 重复的ID属性(最关键的问题)
你给<canvas>和<video>都设置了id="can",但HTML要求页面内的ID必须唯一!当你执行document.getElementById('can')时,浏览器只会返回DOM中后出现的那个元素(也就是你的video元素),这就导致canvas变量实际指向的是视频元素,而不是画布。视频元素没有getContext()方法,所以ctx会是undefined,自然无法在画布上绘制任何内容。
2. 元素层级与鼠标事件遮挡
就算ID改对了,你的Canvas和Video是绝对定位完全重叠的。因为Video在DOM中是后渲染的,它默认会覆盖在Canvas上方。这意味着即使视频暂停了,鼠标事件也会被Video元素捕获,Canvas根本接收不到mousedown、mousemove这些绘图必需的事件。
修正后的完整代码
下面是修复后的代码,我标注了关键修改点:
<html> <body> <!-- 修改1:给Canvas保留id="can",给Video设置唯一id="videoPlayer" --> <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;z-index:1;"> </canvas> <video id="videoPlayer" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;z-index:2;"> <source src="Test.mp4" type="video/mp4"> </video> </body> <script type="text/javascript"> var canvas, ctx, flag = false, prevX = 0, currX = 0, prevY = 0, currY = 0, dot_flag = false; var x = "black", y = 2; var video; // 新增:定义视频元素变量 addEventListener("load", init ); function init() { canvas = document.getElementById('can'); ctx = canvas.getContext("2d"); w = canvas.width; h = canvas.height; // 修改2:获取视频元素,并添加暂停/播放事件监听,切换层级 video = document.getElementById('videoPlayer'); video.addEventListener('pause', () => { canvas.style.zIndex = 3; // 暂停时让Canvas在最上层,接收鼠标事件 }); video.addEventListener('play', () => { canvas.style.zIndex = 1; // 播放时让Video回到上层 }); // 以下是原有的绘图事件监听,保持不变 canvas.addEventListener("mousemove", function (e) { findxy('move', e)}, false); canvas.addEventListener("mousedown", function (e) { findxy('down', e) }, false); canvas.addEventListener("mouseup", function (e) { findxy('up', e)}, false); canvas.addEventListener("mouseout", function (e) { findxy('out', e)}, false); } // 原有的draw、erase、save、findxy、color函数保持不变 function draw() { ctx.beginPath(); ctx.moveTo(prevX, prevY); ctx.lineTo(currX, currY); ctx.strokeStyle = x; ctx.lineWidth = y; ctx.stroke(); ctx.closePath(); } function erase() { var m = confirm("Want to clear"); if (m) { ctx.clearRect(0, 0, w, h); document.getElementById("canvasimg").style.display = "none"; } } function save() { document.getElementById("canvasimg").style.border = "2px solid"; document.getElementById("canvasimg").src = canvas.toDataURL(); document.getElementById("canvasimg").style.display = "inline"; } function findxy(res, e) { if (res == 'down') { prevX = currX; prevY = currY; currX = e.clientX - canvas.offsetLeft; currY = e.clientY - canvas.offsetTop; flag = true; dot_flag = true; if (dot_flag) { ctx.beginPath(); ctx.fillStyle = x; ctx.fillRect(currX, currY, 2, 2); ctx.closePath(); dot_flag = false; } } if (res == 'up' || res == "out") { flag = false; } if (res == 'move') { if (flag) { prevX = currX; prevY = currY; currX = e.clientX - canvas.offsetLeft; currY = e.clientY - canvas.offsetTop; draw(); } } } function color(obj) { switch (obj.id) { case "green": x = "green"; break; case "blue": x = "blue"; break; case "red": x = "red"; break; case "yellow": x = "yellow"; break; case "orange": x = "orange"; break; case "black": x = "black"; break; case "white": x = "white"; break; } if (x == "white") y = 14; else y = 2; } </script> </html>
关键修改说明
- 唯一ID:给Video设置了独立的
id="videoPlayer",确保getElementById能正确获取到Canvas元素。 - 动态层级切换:通过监听Video的
pause和play事件,动态调整Canvas和Video的z-index:- 视频暂停时,Canvas的层级升高,能接收鼠标事件并显示绘制内容;
- 视频播放时,Video回到上层,正常播放视频。
这样修改后,你就能在视频暂停时顺利在Canvas上绘图,播放时又能正常观看视频啦!
内容的提问来源于stack exchange,提问作者Sreevathsabr
相关产品推荐
相关产品推荐

