Search code examples
actionscript-3html5-canvasanimate-cc

TypeError: Cannot read property of instance


I'm trying to make eye following for cursor like this http://www.flashuser.net/eyes-following-mouse-cursor-as3 in Adobe Animate 2015

function getMousePos(canvasDom, mouseEvent) {
  var rect = canvasDom.getBoundingClientRect();
  return {
    x: mouseEvent.clientX - rect.left,
    y: mouseEvent.clientY - rect.top
  };
}

canvas.addEventListener("mousemove", function (e) {
    mousePos = getMousePos(this, e);

    var xx = mousePos.x - this.Reye.x;
    var yy = mousePos.y - this.Reye.y;
    var radiusR1 = Math.atan2(yy, xx);
    var degreeR1 = radiusR1 / (Math.PI / 180);
    this.Reye.rotation = degreeR1;

}, false);

but i have error in browser

TypeError: Cannot read property 'x' of undefined

and this code is working fine

this.addEventListener("click", fl_MouseClickHandler.bind(this));
function fl_MouseClickHandler(evt)
{
    var xx = stage.mouseX - this.Reye.x;
    var yy = stage.mouseY - this.Reye.y;
    var radiusR1 = Math.atan2(yy, xx);
    var degreeR1 = radiusR1 / (Math.PI / 180);
    this.Reye.rotation = degreeR1;
}

Solution

  • Your scope is wrong.

    You add an anonymous function as a listener inline:

    canvas.addEventListener("mousemove", function (e) {
    

    This is bad practise btw., because you have a hard time removing the listener again. A lingering listener will prevent objects from getting collected and can cause memory leaks.

    Anyway, the scope of an anonymous function (closure) is the global object. this will not point to the scope where the function is defined.

    In your second example, you bind the scope:

    fl_MouseClickHandler.bind(this)
    

    which shouldn't be necessary for a named function.

    On a side note: use types and use defined constants for Event types, such as MouseEvent.CLICK for "click" - prevents typos and allows code completion.