Drag-and-Drop in Flash CS3

Some applications require that the user only drop a dragged object to a few predefined points or areas of the screen. This example takes the basic drag-and-drop interface we created on page 1 and adds a grid of valid points. This gives a "snap to grid" effect that is familiar to those who use graphics programs.

The applet shown below is very similar to the basic triangle we just built on Page 2. However, if you take a moment to try the interface, two things will jump out at your. First of all, we are able to move any of the three points, and secondly, there is an awesome drop shadow effect on the triangle while a point is being moved. It is pretty surprising just how little is different in this application from the one we made before. In fact, all of the code listed as "Part I" on Page 2 is exactly the same in this application. That is, the initial layout of the graphics objects is the same.

Believe it our not, there is not a huge change in the drag-and-drop part of our code. We can make all three points draggable with the same code and using a little understanding of two particular issues ActionScript.

When we set a variable equal to a complex object like a Sprite (as opposed to something simple like a number or string), that variable actually just "points at" (or "references") that object. Hence, a global variable called thisPt can be set equal to any one our three "drag points" and then anything we say to do to thisPt is actually done to that particular point.

The script knows which point is clicked because that information is sent as a property of the MOUSE_DOWN event to the function registered with this event. In the code for the pointMove function below

// Part II -- Add drag and drop functionality

var thisPt:Sprite = new Sprite();

dragPt1.addEventListener(MouseEvent.MOUSE_DOWN, startMove);

dragPt2.addEventListener(MouseEvent.MOUSE_DOWN, startMove);

dragPt3.addEventListener(MouseEvent.MOUSE_DOWN, startMove);

function startMove(evt:MouseEvent):void {

thisPt = Sprite(evt.currentTarget);

triangle.filters = [ new DropShadowFilter() ];

stage.addEventListener(MouseEvent.MOUSE_MOVE, pointMove);

}

function pointMove(e:MouseEvent):void {

thisPt.x = goodX(board.mouseX);

thisPt.y = goodY(board.mouseY);

drawTriangle();

e.updateAfterEvent();

}

stage.addEventListener(MouseEvent.MOUSE_UP, stopAll);

function stopAll(e:MouseEvent):void {

triangle.filters = [ ];

stage.removeEventListener(MouseEvent.MOUSE_MOVE, pointMove);

}

Our helper functions in this case simply draw the triangle whenever called upon to do so (which happens in the above code whenever the mouse moves while dragging has been activated by a mouse down event). As always we have goodX and goodY functions that keep our dragged objects inside of their box.

// Part III -- Helper functions to clear/redraw triangle and stay within boundary

function drawTriangle():void {

triangle.graphics.clear();

triangle.graphics.lineStyle(1,0);

triangle.graphics.beginFill(0xFFAAFF);

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

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

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

triangle.graphics.lineTo(dragPt1.x,dragPt1.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;

}

// Initial triangle drawing

drawTriangle();

Download

Notes

For some applications, we would like to further limit the places to which an object can be dragged. On Page 6 of this tutorial, we show a mathematical situation where we want the vertices of our triangle to only be on lattice points. To do this, we need to learn how to accomplish the "snap-to-grid" effect common in many graphics programs. We address this on the next page.