如何在javascript中制作多个点击响应画布?

时间:2017-07-07 01:18:03

标签: javascript html5 canvas

下面的代码应该在它所在的画布中的工具提示处创建10x10彩色框,在灰色背景上在红色和蓝色之间交替。我希望每个画布仅在画布内时才响应鼠标。下面的代码制作了4个方形灰色画布,但是当鼠标位于最左边的画布上时,最右边的画布上会出现彩色框。没有其他画布可以工作。

所以这是我的两个问题。

  1. 为什么只有一个画布处于活动状态?
  2. 为什么盒子出现在错误的画布上?
  3. <!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>

1 个答案:

答案 0 :(得分:1)

这是因为您没有声明变量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>