javascript - 如何在 JavaScript 中制作多次点击响应式 Canvas ?

标签 javascript html canvas

下面的代码应该在其所在 Canvas 的工具提示处创建 10x10 彩色框,在灰色背景上交替显示红色和蓝色。我希望每个 Canvas 仅当鼠标位于 Canvas 内时才响应鼠标。下面的代码制作了 4 个方形灰色 Canvas ,但是当鼠标悬停在最左边的 Canvas 上时,最右边的 Canvas 中会出现彩色框。其他 Canvas 都不起作用。

这是我的两个问题。

  1. 为什么只有一张 Canvas 处于事件状态?
  2. 为什么方框出现在错误的 Canvas 上?

<!DOCTYPE html>
<html>
<body>
<canvas id="c0" width="201" height="201"></canvas>
<canvas id="c1" width="201" height="201"></canvas>
<canvas id="c2" width="201" height="201"></canvas>
<canvas id="c3" width="201" height="201"></canvas>

<script>
var colorno = ["#F77", "#077"];
var the = { 'c0': {}, 'c1': {}, 'c2': {}, 'c3': {} };
var box = 10;
var workings = function(name) {
    instance = the[name];
    instance.name = name;
    canvas = instance.canvas = document.getElementById(instance.name);
    instance.context = canvas.getContext("2d");
    instance.index = 0;
    instance.context.fillStyle = "#777";
    instance.context.fillRect(0, 0, canvas.width, canvas.height);
    scale = (canvas.width - box) / canvas.width;
    canvas.addEventListener("click", function(e) {
        instance.context.fillStyle = colorno[++instance.index&1];
        instance.context.fillRect(scale*e.x-box, scale*e.y-box, box, box);
    }, true);
};
for (var key in the) workings(key);
</script>

</body>
</html>

最佳答案

这是因为你没有声明变量instance,导致它被定义在全局范围内。 instance 不断被 for 循环覆盖,因此在所有 4 个处理程序中,instance 变量都指向同一个对象。在闭包中正确声明变量非常重要。

var instance = value;      // declare function-scoped variable
let instance = value;      // declare block-scoped variable
function workings(args){}  // declare a function

以下是已修复的代码版本:

<!DOCTYPE html>
<html>
<body>
<canvas id="c0" width="201" height="201"></canvas>
<canvas id="c1" width="201" height="201"></canvas>
<canvas id="c2" width="201" height="201"></canvas>
<canvas id="c3" width="201" height="201"></canvas>

<script>
var colorno = ["#F77", "#077"];
var the = { 'c0': {}, 'c1': {}, 'c2': {}, 'c3': {} };
var box = 10;

// declare function
function workings(name) {
    // declare variables
    var instance = the[name];
    var canvas = instance.canvas = document.getElementById(name);
    // assign values
    instance.name = name;
    instance.context = canvas.getContext("2d");
    instance.index = 0;
    instance.context.fillStyle = "#777";
    instance.context.fillRect(0, 0, canvas.width, canvas.height);

    // attach click listener
    canvas.addEventListener("click", function(e) {
        instance.context.fillStyle = colorno[++instance.index&1];
        instance.context.fillRect(
          // calculate correct coordinates
          e.pageX - canvas.offsetLeft - box / 2,
          e.pageY - canvas.offsetTop - box / 2, 
          box, box);
    }, true);
};

// invoke function
for (var key in the) workings(key);
</script>

</body>
</html>

关于javascript - 如何在 JavaScript 中制作多次点击响应式 Canvas ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44961114/

相关文章:

javascript - 如何根据输入的行数生成html表格?

javascript - 单击 Canvas 中的线条

javascript - 在运行时使折线更长

javascript - 如何将自定义 HTTP header 添加到 BackboneJS 模型中的所有 AJAX 调用?

javascript - 如何克隆选定的div

javascript - 使用多个 Id 标签来激活一个封闭的跨度元素

php - 如何安全地允许嵌入内容?

javascript - 在这种情况下,document.createElement 或 document.write 哪个更好?

python - 通过 Selenium/Python 抓取 <canvas> 像素

javascript - jquery - 取消同一页面其他部分发生的警报