Search code examples
javascriptdrag-and-dropeaseljsanimate-cc

Drag and Drop not recognizing child of drag object in Animate CC


I'm trying to make a drag and drop, but it's been giving me a bunch of issues. I fix one and another comes up. I had it working where it would see if any part of my drag object entered a target area, but I wanted it to just recognize one part (it's graphic of a pointy thermometer, and you can't measure temperature with the head in real life) demo here.

The error I'm getting is that "Uncaught TypeError: Cannot read property 'drag' of undefined" (I labeled 'drag' on the demo, but its a child movieclip inside the drag object)

also, 'thermometer' and 'drag' are both named instances of movieclips.

The Code:

var dragger = this.thermometer; 

//tried this to see if it would help
var tip = this.thermometer.drag;
var right = this.targetRight;
var wrong = this.targetWrong; 
  • For moving it:

    dragger.on("pressmove", function(evt){
    evt.currentTarget.x = evt.stageX;
    evt.currentTarget.y = evt.stageY;
    
    
    if(intersect(tip, right)){
       evt.currentTarget.alpha=0.2;
    
     }
     else if(intersect(tip, wrong)){
       evt.currentTarget.alpha=0.7;
    
     }
     else{
       evt.currentTarget.alpha=1;
    
     }
    
    stage.update(evt);
    }, this);
    
  • For releasing it

    dragger.on("pressup", function(evt){ 
    //lock position of drag object and play animation if any
    dragger.x = dragger.x;
    dragger.y = dragger.y;
    
    if(hitTestArray.length > 1){
      dragger.alpha = 1;
      stage.update(evt);
    }//else{
    
        if(intersect(tip, right)){  //Intersection testing for good (also tried 'dragger.drag' to see if that would work. it didn't)
    
            alert("YAY you're right AND it works!");
            dragger.alpha = 1;
    
        }else if(intersect(tip, wrong)){  //intersection Testing for bad
    
            alert("BOO its wrong, but YAY it works"); 
            dragger.alpha = 1;
        }
    
      stage.update(evt);
    //}
    }, this);
    

UPDATED INTERSECT:

  • for testing intersection.

    function intersect(obj1, obj2){
      var objBounds1 = obj1.nominalBounds.clone();
      var objBounds2 = obj2.nominalBounds.clone();
    
      var pt = obj1.globalToLocal(objBounds2.x, objBounds2.y);
    
    
    
      var h1 = -(objBounds1.height / 2 + objBounds2.height);
      var h2 = objBounds2.height / 2;
      var w1 = -(objBounds1.width / 2 + objBounds2.width);
      var w2 = objBounds2.width / 2;
    
    
      if(pt.x > w2 || pt.x < w1) return false;
      if(pt.y > h2 || pt.y < h1) return false;
    
      return true;
    }
    

To sum up, I need to know how to make it not undefined so that I can test for that little box being in one of the big boxes.


Solution

  • The error is happening because you used this.currentTarget instead of evt.currentTarget on that one line.

    Note that your actual code is not the same as the code you posted above. Here is the code in the live demo:

    if(intersect(this.currentTarget.drag, right)){
        evt.currentTarget.alpha=0.2;
    } else if(intersect(this.currentTarget.drag, wrong)){
        evt.currentTarget.alpha=0.7;
    }
    else{
        evt.currentTarget.alpha=1;
    }
    

    Not sure if this will solve all your issues, but it should at least get you moving forward.


    [UPDATE]

    Looking a little deeper, there a number of issues that are likely contributing to your intersect function not working:

    1. Your right/left bounds are not correct. EaselJS objects do not have a width or height (more info), so the bounds you set just have an x and y.

    You can use nominalBounds to get the proper bounds. This provides the untransformed, original bounds of the symbol. You will have to account for any scaling. In this case, the bounds are: * left: {x: 0, y: 0, width: 275, height: 300} * right: {x: 0, y: 0, width: 413, height: 430}

    1. Your intersection will have to consider the display list hierarchy. Specifically, when comparing position and size, they should be relative to each other. If your drag target is positioned inside another clip, it will need to consider the parent positioning. I recommend always doing localToGlobal on coordinates when comparing them.

    Example:

    // Find the clip's top/left position in the global scope
    var p = myContainer.localToGlobal(myClip.x, myClip.y); 
    // OR 
    // Find the clip's position in the global scope
    var p = myClip.localToGlobal(0, 0);