JavaScript Canvas不适用于onchange事件

时间:2017-04-04 10:09:52

标签: javascript events canvas onchange

如果删除此部分,以下代码有效:

checkboxPencil.onchange = function() {
    if(checkboxPencil.checked) {

如果它有效,我可以在画布上画画,如果不是,我不能。

因为我想在onc​​hange上做一些事情我需要用onchange事件包装我的函数并检查是否选中了Checkbox。

但我不明白为什么这对上面的2行不起作用。 我在Chrome开发者控制台中没有收到任何错误。

如果我删除上面的2行,我的代码再次起作用,但是如果我添加它们并且我不明白为什么它就不起作用。

完整代码:

if(window.addEventListener) {
    window.addEventListener('load', function () {

    ...

    // Initialization sequence.
    function init () {

        canvas = document.getElementById('imageView');


        tool = new tool_pencil();

        canvas.addEventListener('mousedown', ev_canvas, false);
        canvas.addEventListener('mousemove', ev_canvas, false);
        canvas.addEventListener('mouseup', ev_canvas, false);
    }

    function tool_pencil() {

        var tool = this;
        this.started = false;

        checkboxPencil.onchange = function() {
            if(checkboxPencil.checked) {
                console.log("Pencil checked");

                this.mousedown = function (ev) {
                    context.beginPath();
                    context.moveTo(ev._x, ev._y);
                    tool.started = true;
                };

                this.mousemove = function (ev) {
                    if (tool.started) {
                        context.lineTo(ev._x, ev._y);
                        context.stroke();
                    }
                };

                this.mouseup = function (ev) {
                    if (tool.started) {
                        tool.mousemove(ev);
                        tool.started = false;
                    }
                };
            } else {
                console.log("Pencil not checked");
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

问题正在发生,因为那些鼠标事件侦听器回调函数在您将它们添加到画布时尚未初始化。

在绘制画布之前,您应该检查是否选中了复选框。

window.addEventListener('load', init);

function init() {
    canvas = document.getElementById('imageView');
    checkboxPencil = document.getElementById('checkboxPencil');
    context = canvas.getContext("2d");
    tool = new tool_pencil();
    canvas.addEventListener('mousedown', tool.mousedown, false);
    canvas.addEventListener('mousemove', tool.mousemove, false);
    canvas.addEventListener('mouseup', tool.mouseup, false);
}

function tool_pencil() {
    this.started = false;
    this.mousedown = function(ev) {
        if (checkboxPencil.checked) {
            context.beginPath();
            context.moveTo(ev.offsetX, ev.offsetY);
            this.started = true;
        }
    };
    this.mousemove = function(ev) {
        canvas.style.cursor = 'default';
        if (this.started && checkboxPencil.checked) {
            context.lineTo(ev.offsetX, ev.offsetY);
            context.stroke();
        }
    };
    this.mouseup = function(ev) {
        if (this.started && checkboxPencil.checked) {
            this.started = false;
        }
    };
}
canvas {
  border: 1px solid black;
}
<canvas id="imageView" width="300" height="300"></canvas>
<input type="checkbox" id="checkboxPencil">Pencil

答案 1 :(得分:0)

我没有足够的上下文来运行你的代码,但我想我至少可以猜到问题的一部分......

我假设checkboxPencil已初始化为var checkboxPencil = document.getElementById('my_checkbox_element')或类似。要使其正常工作,需要在window.onload代码中,在您省略的部分中声明checkboxPencil

我还假设tool在省略的部分或全局声明。否则,行tool = new tool_pencil()将无效。

而且,我假设ev_canvas是一个调用tool对象的相关mousedown / mouseup / mousemove方法的函数。

如果所有这些假设都是正确的,那么最明显的问题是你将mousedown等函数附加到错误的对象上。因为您正在HTML复选框元素的onchange处理程序中进行分配,所以当代码运行时,this将引用复选框元素,封闭{{1}对象。我相信你想改变这条线

tool_pencil

(等)到

this.mousedown = function (ev) {

在此上下文中,tool.mousedown = function (ev) {通过闭包引用tool函数的局部变量tool

另一个问题是它看起来不像tool_pencil。您可能希望在代码的省略部分中声明它,然后在初始化context后立即添加行

canvas