如何解决动态生成的多canvas仅最后一个可正常绘制的问题
问题根因
你代码中的canvas、ctx、绘制状态(flag、坐标变量等)都是全局变量,每次调用initEditableImageCanvas初始化新的canvas时,都会覆盖这些全局变量的值。所有canvas绑定的事件触发时,操作的都是最后一次初始化的canvas实例,因此只有最后一个canvas可以正常绘制。
修复方案
将所有canvas相关的状态变量、事件处理函数都封装在initEditableImageCanvas内部,让每个canvas实例拥有独立的上下文和状态,避免全局变量覆盖导致的冲突。
修改后的完整JS代码如下:
<script> // 全局通用的画笔配置可保留为全局变量 var x = "red", y = 2; function initEditableImageCanvas(fieldId) { // 所有实例专属变量放在函数内部,每个canvas独立持有 var canvas = document.getElementById('image-canvas-' + fieldId); var ctx = canvas.getContext("2d"); var w = canvas.width; var h = canvas.height; var flag = false, prevX = 0, currX = 0, prevY = 0, currY = 0, dot_flag = false; // 绘制函数放在内部,通过闭包访问当前canvas的状态 function draw() { ctx.beginPath(); ctx.moveTo(prevX, prevY); ctx.lineTo(currX, currY); ctx.strokeStyle = x; ctx.lineWidth = y; ctx.stroke(); ctx.closePath(); } function findxy(res, e) { if (res == 'down') { prevX = currX; prevY = currY; currX = e.clientX - canvas.getBoundingClientRect().left; currY = e.clientY - canvas.getBoundingClientRect().top; 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.getBoundingClientRect().left; currY = e.clientY - canvas.getBoundingClientRect().top; draw(); } } } 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); } $(document).ready(function() { $(".image-canvas").each(function() { initEditableImageCanvas($(this).data("fieldid")); }); }); </script>
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

