You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

关键修改说明

  1. 唯一ID:给Video设置了独立的id="videoPlayer",确保getElementById能正确获取到Canvas元素。
  2. 动态层级切换:通过监听Video的pause和play事件,动态调整Canvas和Video的z-index:
    • 视频暂停时,Canvas的层级升高,能接收鼠标事件并显示绘制内容;
    • 视频播放时,Video回到上层,正常播放视频。

这样修改后,你就能在视频暂停时顺利在Canvas上绘图,播放时又能正常观看视频啦!

内容的提问来源于stack exchange,提问作者Sreevathsabr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:03:17