Drag-and-Drop in Flash CS3

The application below shows a dynamically changing filled triangle with one draggable vertex (the green one). It is easy to imagine the mathematical content we could add to this applet to make this a pedagogically meaningful application. Indeed, we will end this series of tutorials with one such application (Pick's Theorem) once we address the technique of snapping dragged objects to a grid. investigate the interface with the applet below before reading on to see how it is done.

We will give the full set of code for this application. We now have three circle sprites (colored differently so it is clear which is which), two fixed and one that will be endowed with the drag and drop behavior we learned about earlier. In addition, we have a Shape object called "triangle" that will consist of a filled figure resulting from connecting the three dots. The triangle is a "shape" rather than a "sprite" because we will not need to add children to the triangle and we will not need the triangle to react directly to any events. We accomplish the effect you see by literally clearing and redrawing the triangle every time the "mouse move" event is heard. Thanks to the processing and rendering speeds of the Flash player, the effect is smooth and seamless. Note that now the order that the objects are placed is more important. To get a sense for this, move the line that adds the "triangle" shape as a child to the "board" down below one or more of the lines that adds a point as a child to the board. Test this version to see the difference.

// Part I-- Create the display objects with correct relationships

var bWidth:Number = 400;

var bHeight:Number = 300;

var board:Sprite = new Sprite();

var triangle:Shape = new Shape();

var fixPt1:Sprite = new Sprite();

var fixPt2:Sprite = new Sprite();

var dragPt:Sprite = new Sprite();

this.addChild(board);

board.addChild(triangle);

board.addChild(fixPt1);

board.addChild(fixPt2);

board.addChild(dragPt);

board.graphics.lineStyle(1,0);

board.graphics.beginFill(0xCCCCCC);

board.graphics.drawRect(0,0,bWidth,bHeight);

board.graphics.endFill();

board.x = 20;

board.y = 50;

fixPt1.graphics.lineStyle(1,0);

fixPt1.graphics.beginFill(0xFF0000);

fixPt1.graphics.drawCircle(0,0,5);

fixPt1.graphics.endFill();

fixPt1.x = 50;

fixPt1.y = 50;

fixPt2.graphics.lineStyle(1,0);

fixPt2.graphics.beginFill(0x0000FF);

fixPt2.graphics.drawCircle(0,0,5);

fixPt2.graphics.endFill();

fixPt2.x = 50;

fixPt2.y = 250;

dragPt.graphics.lineStyle(1,0);

dragPt.graphics.beginFill(0x00FF00);

dragPt.graphics.drawCircle(0,0,5);

dragPt.graphics.endFill();

dragPt.x = 150;

dragPt.y = 150;

// Part II -- Enable the drag and drop behavior for one of the points

dragPt.addEventListener(MouseEvent.MOUSE_DOWN, startMove);

function startMove(evt:MouseEvent):void {

stage.addEventListener(MouseEvent.MOUSE_MOVE, pointMove);

}

function pointMove(e:MouseEvent):void {

dragPt.x = goodX(board.mouseX);

dragPt.y = goodY(board.mouseY);

drawTriangle();

e.updateAfterEvent();

}

stage.addEventListener(MouseEvent.MOUSE_UP, stopAll);

function stopAll(e:MouseEvent):void {

stage.removeEventListener(MouseEvent.MOUSE_MOVE, pointMove);

}

// Part III -- Helper functions

function drawTriangle():void {

triangle.graphics.clear();

triangle.graphics.lineStyle(1,0);

triangle.graphics.beginFill(0xFFAAFF);

triangle.graphics.moveTo(fixPt1.x,fixPt1.y);

triangle.graphics.lineTo(fixPt2.x,fixPt2.y);

triangle.graphics.lineTo(dragPt.x,dragPt.y);

triangle.graphics.lineTo(fixPt1.x,fixPt1.y);

triangle.graphics.endFill();

}

function goodX(inX:Number):Number {

if (inX < 0) {

return 0;

}

if (inX > bWidth) {

return bWidth;

}

return inX;

}

function goodY(inY:Number):Number {

if (inY < 0) {

return 0;

}

if (inY > bHeight) {

return bHeight;

}

return inY;

}

// Initially draw the triangle

drawTriangle();

Download

Notes

The interface is smooth, and it is easy to see how we could add more helper functions like drawTriangle that can be updated whenever the dragPt is moved. For example, after the addition of a scale for our "board" it would be simple to display continually updating edge lengths, triangle perimeter and area on the screen. With more sophisticated mathematics, it would not be too difficult to display perpendicular bisectors to each line continually updating as the point is dragged.

We are allowing the triangle to be degenerate (i.e., a line segment). Perhaps for educational purposes we want to allow this, but for some applications this can cause spurious results.

We are only dragging one of the three vertices, which is somewhat limiting from both a mathematics perspective and a user interface perspective. (It is hard to resist trying to drag the fixed points above even in this context where nothing else is happening!)