Search code examples
javascriptpaperjs

Trying to access object property from another object always returns the property's initial value


I have created two classes of objects in PaperScript: Nodes and Lines. Each Line has a this.nodes property which is an array that references two Node objects, one for each end of the line. Nodes have a this.dragging property which is initialized as false when the Node object is created, but gets set to true on a onMouseDown event and gets set back to false at onMouseUp. This is so that I can keep track whether or not the Node is meant to be moving at a point in time.

Now I want to be able to check from the Line objects if its associated Nodes are being dragged at any point in time. For this I have an if statement that checks whether (this.nodes[0].dragging == true || this.nodes[1].dragging == true). If that returns true then further action can happen.

The problem is that both this.nodes[i].draggings always returns false, regardless of whether I am dragging the Node or not. Why does this happen? Especially when I check the value of this.dragging from within the Node object it does return the correct value of true when dragging and false otherwise.

EDIT included some code:

The following is a condensed version of my code. The important bit is the this.dragging variable.

function Node(pos) {

 ///// Stuff

  this.dragging = false;
  this.node.onMouseDown = function(event) {
    this.dragging = true;
    // Do other stuff
  }
  this.node.onMouseDrag = function(event) {
    if (this.dragging == true) {
       // Do stuff
    }
  }
  this.node.onMouseUp = function(event) {
    // Do stuff
    this.dragging = false;
  }
}

The following is (part of) the constructor for the Line object:

function Line(p1, p2) {
  this.nodes = [p1, p2];

  ///// Stuff

  this.update = function() {
    if (this.nodes[0].dragging === true || this.nodes[1].dragging === true) {
      // True
    } else {
      // False
    }
  }
}

2nd EDIT commenter requested how I instantiate these objects:

I instantiate them as follows:

var nodeNum = 7;
var lineConnections = [{
    from: 0,to: 1}
    ,{from: 0,to: 2}
    ,{from: 0,to: 3}
    ,{from: 0,to: 4}
    ,{from: 1,to: 2}
    ,{from: 1,to: 5}
    ,{from: 2,to: 3}
    ,{from: 2,to: 4}
    ,{from: 3,to: 5}
    ,{from: 4,to: 5}
    ,{from: 2,to: 5}
]

function init() {
  for (var i = 0; i < nodeNum; i++) {
    Nodes[i] = new Node();
  }

  for (var i = 0; i < lineConnections.length; i++) {
    Lines[i] = new Line(Nodes[lineConnections[i].from], Nodes[lineConnections[i].to]);
  }
}

init();

A live demo is available at http://aronadler.com/experiment/


Solution

  • I believe the problem is that this, as in this.dragging in the following code refers to the global object (window), not the object you created.

    this.node.onMouseDown = function(event) { this.dragging = true; // Do other stuff } this.node.onMouseDrag = function(event) { if (this.dragging == true) { // Do stuff } } this.node.onMouseUp = function(event) { // Do stuff this.dragging = false; }

    You can check by seeing if the global variable dragging has been created. I can't really modify your code unless it's in fiddle or some other location where it's easy to work with, but you should be able to fix it either by binding each of the mouse handling functions to this as in: this.node.onMouseUp = function(event) { // Do stuff this.dragging = false; }.bind(this) or by creating a closure with a local reference to this that won't change, as in:

    self = this;

    then refer to self from within the functions as opposed to this.