0x800a138f - JavaScript运行时错误:无法获取未定义或空引用的属性“getLayer”

时间:2013-11-19 00:09:40

标签: javascript html html5 html5-canvas kineticjs

锚点重叠时代码中断。我有用于调整可拖动形状组的大小的锚点,如下面的教程中所示。

我还具有删除所选组的功能。当锚点(两个不同的组)重叠并且选择了重叠锚点(mousedown)时,删除功能会破坏代码。

if (layer !== null && e.keyCode == 46) {  //Delete Key = 46
    SelectedShape.remove();
    layer.batchDraw();
    }
});

//Selecting on mousedown
layer.on('mousedown', function (evt) {
    SelectedShape = evt.targetNode.getParent();
});
  

错误消息:0x800a138f - JavaScript运行时错误:无法获取   未定义或空引用的属性'getLayer'

http://www.html5canvastutorials.com/labs/html5-canvas-drag-and-drop-resize-and-invert-images/

示例代码

var SelectedShape = null;

function update(activeAnchor) {
    var group = activeAnchor.getParent();
    var topLeft = group.get('.topLeft')[0];
    var topRight = group.get('.topRight')[0];
    var bottomRight = group.get('.bottomRight')[0];
    var bottomLeft = group.get('.bottomLeft')[0];
    var rect = group.get('.rect')[0];

    var anchorX = activeAnchor.getX();
    var anchorY = activeAnchor.getY();

    // update anchor positions
    switch (activeAnchor.getName()) {
        case 'topLeft':
            topRight.setY(anchorY);
            bottomLeft.setX(anchorX);
            break;
        case 'topRight':
            topLeft.setY(anchorY);
            bottomRight.setX(anchorX);
            break;
        case 'bottomRight':
            bottomLeft.setY(anchorY);
            topRight.setX(anchorX);
            break;
        case 'bottomLeft':
            bottomRight.setY(anchorY);
            topLeft.setX(anchorX);
            break;
    }

    rect.setPosition(topLeft.getPosition());

    var width = topRight.getX() - topLeft.getX();
    var height = bottomLeft.getY() - topLeft.getY();
    if (width && height) {
        rect.setSize(width, height);
    }
}
function addAnchor(group, x, y, name) {
    var stage = group.getStage();
    var layer = group.getLayer();

    var anchor = new Kinetic.Circle({
        x: x,
        y: y,
        stroke: '#666',
        fill: '#ddd',
        strokeWidth: 2,
        radius: 8,
        name: name,
        draggable: true,
        dragOnTop: false
    });

    anchor.on('dragmove', function () {
        update(this);
        layer.draw();
    });
    anchor.on('mousedown touchstart', function () {
        group.setDraggable(false);
        this.moveToTop();
    });
    anchor.on('dragend', function () {
        group.setDraggable(true);
        layer.draw();
    });
    group.add(anchor);
}

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 578,
        height: 400
    });
    var darthVaderGroup = new Kinetic.Group({
        x: 270,
        y: 100,
        draggable: true
    });
    var yodaGroup = new Kinetic.Group({
        x: 100,
        y: 110,
        draggable: true
    });

    var Group3 = new Kinetic.Group({
        x: 100,
        y: 300,
        draggable: true
    });
    var layer = new Kinetic.Layer();

    /* add the groups to the layer and the layer to the stage*/
    layer.add(darthVaderGroup);
    layer.add(yodaGroup);
    layer.add(Group3);
    stage.add(layer);

    // darth vader
    var darthVaderImg = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 200,
        height: 138,
        fill: 'green',
        stroke: 'black',
        strokeWidth: 4,
        name: 'rect'
    });

    darthVaderGroup.add(darthVaderImg);
    addAnchor(darthVaderGroup, 0, 0, 'topLeft');
    addAnchor(darthVaderGroup, 200, 0, 'topRight');
    addAnchor(darthVaderGroup, 200, 138, 'bottomRight');
    addAnchor(darthVaderGroup, 0, 138, 'bottomLeft');

    darthVaderGroup.on('dragstart', function () {
        this.moveToTop();
    });
    // yoda
    var yodaImg = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 93,
        height: 104,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4,
        name: 'rect'
    });

    yodaGroup.add(yodaImg);
    addAnchor(yodaGroup, 0, 0, 'topLeft');
    addAnchor(yodaGroup, 93, 0, 'topRight');
    addAnchor(yodaGroup, 93, 104, 'bottomRight');
    addAnchor(yodaGroup, 0, 104, 'bottomLeft');

    yodaGroup.on('dragstart', function () {
        this.moveToTop();
    });

    var rect3 = new Kinetic.Rect({
        x: 0,
        y: 0,
        width: 93,
        height: 104,
        fill: 'blue',
        stroke: 'black',
        strokeWidth: 4,
        name: 'rect'
    });

    Group3.add(rect3);
    addAnchor(Group3, 0, 0, 'topLeft');
    addAnchor(Group3, 93, 0, 'topRight');
    addAnchor(Group3, 93, 104, 'bottomRight');
    addAnchor(Group3, 0, 104, 'bottomLeft');

    Group3.on('dragstart', function () {
        this.moveToTop();
    });

    stage.draw();

    //Deleting selected shape 
    window.addEventListener('keydown', function (e) {
        if (layer !== null && e.keyCode == 46) {  //Delete Key = 46
            SelectedShape.remove();
            layer.batchDraw();
        }
    });

    //Selecting on mousedown
    layer.on('mousedown', function (evt) {
        SelectedShape = evt.targetNode.getParent();
    });

1 个答案:

答案 0 :(得分:0)

第一个问题:您必须检查null,因为当您按删除时,SelectedShape可以为null。我会将SelectedShape更改为selectedShape。因为它不是构造函数。

第二个问题是在删除一个组形状之前未与锚点分离的事件处理程序。

解决方案:现在以相反的顺序处理锚点,并在删除之前分离事件。代码更改:

    // Deleting selected shape 
    window.addEventListener('keydown', function (e) {
        if (layer !== null && e.keyCode == 46) {  //Delete Key = 46
            if (selectedShape != null) {
                var shapeChildren = selectedShape.getChildren();
                for (var i = shapeChildren.length - 1; i >= 0 ; i--)
                    detachChild(shapeChildren[i]);

                selectedShape.remove();

                // layer.draw() what is better
                layer.batchDraw();
            }
        }   
    });

事件分离和部件移除:

function detachChild(childShape) {
    if (childShape instanceof Kinetic.Circle) {
        detachAnchor(childShape);
    } else {
        // image
        childShape.remove();
    }
}

function detachAnchor(anchor) {
    anchor.off("dragmove");
    anchor.off("mousedown touchstart");
    anchor.off("dragend");
    anchor.off("mouseover");
    anchor.off("mouseout");

    anchor.remove();
}

我还尝试使用removeChildren()destroyChildren(),但没有设法让它没有错误。

<强> Demo at JS Bin