/ascb/display/DraggableSprite.as

https://github.com/metrobg/GLC-Flex
ActionScript | 112 lines | 47 code | 17 blank | 48 comment | 10 complexity | edda45c6946d38f33173d41b40509bf2 MD5 | raw file
  1. package ascb.display {
  2. import flash.display.Sprite;
  3. import flash.events.MouseEvent;
  4. import flash.geom.Point;
  5. import flash.geom.Rectangle;
  6. /**
  7. * A DraggableSprite is a Sprite that has the ability to interact
  8. * with the Mouse in drag and drop scenarios. All Sprites have
  9. * the startDrop() and stopDrag() methods, but those methods only
  10. * update the display list during enterFrame events, instead of
  11. * during mouseMove events, which leads to choppy dragging. The
  12. * DraggableSprite provides a drag() method, similar to startDrag()
  13. * and a drop() method, similar to stopDrag(), that enable smooth
  14. * drag and drop operations.
  15. */
  16. public class DraggableSprite extends Sprite {
  17. // Store the location of the cursor within the sprite
  18. // so we can position correctly when the cursor moves
  19. private var x_offset:Number = 0;
  20. private var y_offset:Number = 0;
  21. // Keep track of the area where dragging is allowed
  22. // so the sprite can be kept in bounds.
  23. private var bounds:Rectangle;
  24. /**
  25. * Constructor - nothing to do
  26. */
  27. public function DraggableSprite() {
  28. // do nothing
  29. }
  30. /**
  31. * Starts a smooth dragging operation, forcing the player to redraw
  32. * the Sprite after every mouse move. Cancel the drag() operation
  33. * by calling the drop() method.
  34. */
  35. public function drag( lockCenter:Boolean = false, rectangle:Rectangle = null ):void {
  36. // Save the cursor position in the sprite so we can adjust
  37. // the x and y locations correctly when the cursor position
  38. // chnages based on the lockCenter parameter.
  39. var pt:Point;
  40. if ( !lockCenter ) {
  41. // lockCenter is false, use the mouse coordinates at the point
  42. pt = localToGlobal( new Point( mouseX, mouseY ) );
  43. } else {
  44. // lockCenter is true, ignore the mouse coordinates
  45. // and use (0,0) instead as the point
  46. pt = localToGlobal( new Point( 0, 0 ) );
  47. }
  48. // Save the offset values so we can compute x and y correctly
  49. x_offset = pt.x - x;
  50. y_offset = pt.y - y;
  51. // Save the bounds rectangle
  52. bounds = rectangle;
  53. // Wire the Sprite to the mouse - whenever the mouse moves
  54. // invoke handleDrag to update the Sprite position
  55. stage.addEventListener( MouseEvent.MOUSE_MOVE, handleDrag );
  56. // Detect a drop by listening for mouse up on the stage
  57. stage.addEventListener( MouseEvent.MOUSE_UP, drop );
  58. }
  59. /**
  60. * Called everytime the mouse moves after the drag() method has
  61. * been called. Updates the position of the Sprite based on
  62. * the location of the mouse cursor.
  63. */
  64. private function handleDrag( event:MouseEvent ):void {
  65. // Set the x and y location based on the mouse position
  66. x = event.stageX - x_offset;
  67. y = event.stageY - y_offset;
  68. // Keep sprite in bounds if bounds was specified in drag
  69. if ( bounds != null ) {
  70. if ( x < bounds.left ) {
  71. x = bounds.left;
  72. } else if ( x > bounds.right ) {
  73. x = bounds.right;
  74. }
  75. if ( y < bounds.top ) {
  76. y = bounds.top;
  77. } else if ( y > bounds.bottom ) {
  78. y = bounds.bottom;
  79. }
  80. }
  81. // Force the player to re-draw the sprite after the event.
  82. // This makes the movement look smooth, unlike startDrag()
  83. event.updateAfterEvent();
  84. }
  85. /**
  86. * Cancels a drag() operation
  87. */
  88. public function drop():void {
  89. // The mouse up indicated the drop, so remove the mouse up listener ...
  90. stage.removeEventListener( MouseEvent.MOUSE_UP, drop );
  91. // ... and remove the mouse move listener
  92. stage.removeEventListener( MouseEvent.MOUSE_MOVE, handleDrag );
  93. }
  94. }
  95. }