MovieClip class
class MovieClip extends Sprite
{
 /**
  * Read-only. The MovieClip will advance independently of its parent, even if its parent is paused.
  * This is the default mode.
  **/
 static const String INDEPENDENT = "independent";
 
 /**
  * Read-only. The MovieClip will only display a single frame (as determined by the startPosition property).
  **/
 static const String SINGLE_FRAME = "single";
 
 /**
  * Read-only. The MovieClip will be advanced only when it's parent advances and will be synched to the position of
  * the parent MovieClip.
  **/
 static const String SYNCHED = "synched";
 
 /**
  * Controls how this MovieClip advances its time. Must be one of 0 (INDEPENDENT), 1 (SINGLE_FRAME), or 2 (SYNCHED).
  * See each constant for a description of the behaviour.
  **/
 String mode;
 
 /**
  * Specifies what the first frame to play in this movieclip, or the only frame to display if mode is SINGLE_FRAME.
  */
 int startPosition = 0;
 
 /**
  * Specifies the timeline progression speed.
  * If =0, uses the stage's frameRate
  */
 int frameRate = 0;
 /**
  * Indicates whether this MovieClip should loop when it reaches the end of its timeline.
  */
 bool loop = true;
 
 /**
  * Read-Only. The current frame of the movieclip.
  */
 int get currentFrame {
   return _currentFrame;
 }
 /**
  * Read-Only. The number of frames of the movieclip.
  */
 int get totalFrames {
   return timeline.duration.toInt();
 }
 /**
  * The Timeline that is associated with this MovieClip. This is created automatically when the MovieClip
  * instance is initialized.
  */
 Timeline timeline;
 /**
  * If true, the MovieClip's position will not advance when ticked.
  */
 bool paused = false;
 
 /**
  * If true, actions in this MovieClip's tweens will be run when the playhead advances.
  */
 bool actionsEnabled = true;
 
 /**
  * If true, the MovieClip will automatically be reset to its first frame whenever the timeline adds
  * it back onto the display list. This only applies to MovieClip instances with mode=INDEPENDENT.
  * <br><br>
  * For example, if you had a character animation with a "body" child MovieClip instance
  * with different costumes on each frame, you could set body.autoReset = false, so that
  * you can manually change the frame it is on, without worrying that it will be reset
  * automatically.
  */
 bool autoReset = true;
// properties:
 int _currentFrame = 0;
 int _synchOffset = 0;  
 num _prevPos = -1; // TODO: evaluate using a ._reset Boolean prop instead of -1.
 num _prevPosition = 0;
 final Map<int, int> _managed = new Map<int, int>();
 Map<String, dynamic> props;
 
 /**
  * The MovieClip class associates a TimelineTween Timeline with a {{#crossLink "Sprite"}}{{/crossLink}}. It allows
  * you to create objects which encapsulate timeline animations, state changes, and synched actions. Due to the
  * complexities inherent in correctly setting up a MovieClip, it is largely intended for tool output.
  *
  * Currently MovieClip only works properly if it is tick based (as opposed to time based) though some concessions have
  * been made to support time-based timelines in the future.
  * 
  * @param mode Initial value for the mode property. One of MovieClip.INDEPENDENT, MovieClip.SINGLE_FRAME, or MovieClip.SYNCHED.
  * @param startPosition Initial value for the startPosition property.
  * @param loop Initial value for the loop property.
  * @param labels A hash of labels to pass to the timeline instance associated with this MovieClip.
  **/
 MovieClip([String mode, int startPosition, bool loop, Map<String, num> labels])
   : super() {
   
   this.mode = mode != null ? mode : MovieClip.INDEPENDENT;
   this.startPosition = startPosition != null ? startPosition : 0;
   this.loop = loop != null ? loop : true;
   props = {"paused":true, "position":this.startPosition};
   timeline = new Timeline(null, labels, props);
 }
 
// public methods:
 /**
  * Returns true or false indicating whether the display object would be visible if drawn to a canvas.
  * This does not account for whether it would be visible within the boundaries of the stage.
  * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  * @method isVisible
  * @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
  **/
 bool isVisible() {
   // children are placed in draw, so we can't determine if we have content.
   return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0);
 }
 /**
  * Advances timelines and places children depending on the currentframe
  * NOTE: automatically called by .render()
  */
 void advance(num deltaTime) {
   _advanceTime(deltaTime);
   _updateTimeline();
 }
 
 /**
  * Draws the display object into the specified context ignoring it's visible, alpha, shadow, and transform.
  * Returns true if the draw was handled (useful for overriding functionality).
  * NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
  * @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into.
  * @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache.
  * For example, used for drawing the cache (to prevent it from simply drawing an existing cache back
  * into itself).
  **/
 void render(RenderState renderState) {
   advance(renderState.deltaTime);
   super.render(renderState);
 }
 
 /**
  * Sets paused to false.
  **/
 void play() {
   paused = false;
 }
 
 /**
  * Sets paused to true.
  **/
 void stop() {
   paused = true;
 }
 
 /**
  * Advances this movie clip to the specified position or label and sets paused to false.
  **/
 void gotoAndPlay(dynamic positionOrLabel) {
   paused = false;
   _goto(positionOrLabel);
 }
 
 /**
  * Advances this movie clip to the specified position or label and sets paused to true.
  **/
 void gotoAndStop(dynamic positionOrLabel) {
   paused = true;
   _goto(positionOrLabel);
 }
 
 /**
  * Returns a string representation of this object.
  * @return {String} a string representation of the instance.
  **/
 String toString() {
   return "[MovieClip (name=$name)]";
 }
 
// private methods
 bool _advanceTime(num time) {
   if (!paused && mode == MovieClip.INDEPENDENT && stage != null) {
     var f = frameRate > 0 ? frameRate : stage.frameRate;
     num sPerFrame = 1 / f;
     num df = min(1, time / sPerFrame);
     _prevPosition = (_prevPos < 0) ? 0 : _prevPosition+df;
     timeline._advanceTime(df);
   }
   return true;
 }
 
 void _goto(positionOrLabel) {
   var pos = timeline.resolve(positionOrLabel);
   if (pos == null) return;
   // prevent _updateTimeline from overwriting the new position because of a reset:
   if (_prevPos == -1) { _prevPos = double.NAN; }
   _prevPosition = pos;
   _updateTimeline();
 }
 
 void _reset() {
   _prevPos = -1;
   _currentFrame = 0;
 }
 
 void _updateTimeline() {
   var tl = timeline;
   var tweens = tl._tweens;
   var synched = mode != MovieClip.INDEPENDENT;
   tl.loop = loop;
   
   // update timeline position, ignoring actions if this is a graphic.
   if (synched) {
     // TODO: this would be far more ideal if the _synchOffset was somehow provided by the parent, so that reparenting wouldn't cause problems and we can direct draw. Ditto for _off (though less important).
     tl.setPosition(startPosition + (mode==MovieClip.SINGLE_FRAME?0:_synchOffset), TimelineTween.NONE);
   } else {
     tl.setPosition(_prevPos < 0 ? 0 : _prevPosition, actionsEnabled ? null : TimelineTween.NONE);
   }
   
   _prevPosition = tl._prevPosition;
   if (_prevPos == tl._prevPos) 
     return;
   _prevPos = tl._prevPos;
   _currentFrame = _prevPos.toInt();
   
   for (var n in _managed.keys) { _managed[n] = 1; }
   
   for (var i=tweens.length-1; i>=0; i--) {
     TimelineTween tween = tweens[i];
     var target = tween._target;
     if (target == null || target == this) continue; // TODO: this assumes this is the actions tween. Valid?
     int offset = tween._stepPosition.toInt();
     
     if (target is DisplayObject) {
       // motion tween.
       DisplayObject child = target as DisplayObject; 
       _addManagedChild(child, offset);
     } 
     else {
       // state tween.
       if (target.containsKey("state")) {
         List<dynamic> state = target["state"];
         _setState(state, offset);
       }
     }
   }
   
   for (var i=_children.length-1; i>=0; i--) {
     var id = _children[i]._id;
     if (_managed[id] == 1) {
       removeChildAt(i);
       _managed.remove(id);
     }
   }
 }
 
 void _setState(List<dynamic> state, int offset) {
   if (state == null) return;
   for (var i=0,l=state.length;i<l;i++) {
     var o = state[i];
     var target = o["t"];
     if (target is DisplayObject)
     {
       var d = target as DisplayObject;
       if (o.containsKey("p"))
       {
         var p = o["p"];
         for(var n in p.keys)
         {
           var v = p[n];
           num dv = v is num ? v.toDouble() : 0;  
           switch(n)
           {
             case "off": d.off = v as bool; break;
             case "x": d.x = dv; break;
             case "y": d.y = dv; break;
             case "rotation": d.rotation = dv; break;
             case "alpha": d.alpha = dv; break;
             case "scaleX": d.scaleX = dv; break;
             case "scaleY": d.scaleY = dv; break;
             case "skewX": d.skewX = dv; break;
             case "skewY": d.skewY = dv; break;
             case "regX": d.pivotX = dv; break;
             case "regY": d.pivotY = dv; break;
             case "startPosition":
               if (target is MovieClip)
                 (target as MovieClip).startPosition = dv.toInt();
               break;
             case "mode":
               if (target is MovieClip)
                 (target as MovieClip).mode = v.toString();
               break;
             case "loop":
               if (target is MovieClip)
                 (target as MovieClip).loop = v as bool;
               break;
             case "graphics":
               if (target is Shape)
                 (target as Shape).graphics = v as Graphics;
               break;
             case "textColor":
               if (target is TextField) {
                 var field = target as TextField;
                 if (v is String) field.textColor = int.parse(v.toString());
                 else if (v != null) field.textColor = dv.toInt();
               }
               break;
           }
         }
       }
       _addManagedChild(d, offset);
     }
   }
 }
 
 /**
  * Adds a child to the timeline, and sets it up as a managed child.
  **/
 void _addManagedChild(DisplayObject child, int offset) {
   if (child._off) { return; }
   addChild(child);
   
   if (child is MovieClip) {
     var mc = child;
     mc._synchOffset = offset;
     // TODO: this does not precisely match Flash. Flash loses track of the clip if it is renamed or removed from the timeline, which causes it to reset.
     if (mc.mode == MovieClip.INDEPENDENT && mc.autoReset && !_managed.containsKey(child._id)) { mc._reset(); }
   }
   _managed[child._id] = 2;
 }
 
}
Extends
EventDispatcher > DisplayObject > InteractiveObject > DisplayObjectContainer > Sprite > MovieClip
Static Properties
const String INDEPENDENT #
Read-only. The MovieClip will advance independently of its parent, even if its parent is paused. This is the default mode.
static const String INDEPENDENT = "independent"
Constructors
new MovieClip([String mode, int startPosition, bool loop, Map<String, num> labels]) #
The MovieClip class associates a TimelineTween Timeline with a {{#crossLink "Sprite"}}{{/crossLink}}. It allows you to create objects which encapsulate timeline animations, state changes, and synched actions. Due to the complexities inherent in correctly setting up a MovieClip, it is largely intended for tool output.
Currently MovieClip only works properly if it is tick based (as opposed to time based) though some concessions have been made to support time-based timelines in the future.
@param mode Initial value for the mode property. One of MovieClip.INDEPENDENT, MovieClip.SINGLE_FRAME, or MovieClip.SYNCHED. @param startPosition Initial value for the startPosition property. @param loop Initial value for the loop property. @param labels A hash of labels to pass to the timeline instance associated with this MovieClip.
MovieClip([String mode, int startPosition, bool loop, Map<String, num> labels])
 : super() {
 
 this.mode = mode != null ? mode : MovieClip.INDEPENDENT;
 this.startPosition = startPosition != null ? startPosition : 0;
 this.loop = loop != null ? loop : true;
 props = {"paused":true, "position":this.startPosition};
 timeline = new Timeline(null, labels, props);
}
Properties
bool actionsEnabled #
If true, actions in this MovieClip's tweens will be run when the playhead advances.
bool actionsEnabled = true
num alpha #
num get alpha => _alpha;
set alpha(num value) {
 if (value is num) {
   if (value < 0.0) value = 0.0;
   if (value > 1.0) value = 1.0;
   _alpha = value;
 }
}
bool autoReset #
If true, the MovieClip will automatically be reset to its first frame whenever the timeline adds it back onto the display list. This only applies to MovieClip instances with mode=INDEPENDENT. <br><br> For example, if you had a character animation with a "body" child MovieClip instance with different costumes on each frame, you could set body.autoReset = false, so that you can manually change the frame it is on, without worrying that it will be reset automatically.
bool autoReset = true
String compositeOperation #
String get compositeOperation => _compositeOperation;
set compositeOperation(String value) {
 _compositeOperation = value;
}
final int currentFrame #
Read-Only. The current frame of the movieclip.
int get currentFrame {
 return _currentFrame;
}
List<BitmapFilter> filters #
List<BitmapFilter> get filters {
 if (_filters == null) _filters = new List<BitmapFilter>();
 return _filters;
}
set filters(List<BitmapFilter> value) {
 _filters = value;
}
int frameRate #
Specifies the timeline progression speed. If =0, uses the stage's frameRate
int frameRate = 0
Graphics graphics #
Graphics get graphics {
 return (_graphics != null) ? _graphics : _graphics = new Graphics();
}
set graphics(Graphics value) => _graphics = value;
num height #
num get height => getBoundsTransformed(this.transformationMatrix).height;
void set height(num value) {
 this.scaleY = 1;
 num normalHeight = this.height;
 this.scaleY = (normalHeight != 0.0) ? value / normalHeight : 1.0;
}
bool loop #
Indicates whether this MovieClip should loop when it reaches the end of its timeline.
bool loop = true
Mask mask #
Mask get mask => _mask;
set mask(Mask value) {
 _mask = value;
}
String mode #
Controls how this MovieClip advances its time. Must be one of 0 (INDEPENDENT), 1 (SINGLE_FRAME), or 2 (SYNCHED). See each constant for a description of the behaviour.
String mode
bool mouseChildren #
bool get mouseChildren => _mouseChildren;
void set mouseChildren(bool value) { _mouseChildren = value; }
final Point mousePosition #
Point get mousePosition {
 var stage = this.stage;
 return (stage != null) ? this.globalToLocal(stage._mousePosition) : null;
}
final num mouseX #
num get mouseX {
 var mp = this.mousePosition;
 return (mp != null) ? mp.x : 0.0;
}
final num mouseY #
num get mouseY {
 var mp = this.mousePosition;
 return (mp != null) ? mp.y : 0.0;
}
String name #
String get name => _name;
set name(String value) {
 _name = value;
}
final int numChildren #
int get numChildren => _children.length;
bool off #
bool get off => _off;
set off(bool value) {
 if (value is bool) _off = value;
}
final EventStream<Event> onAdded #
EventStream<Event> get onAdded => DisplayObject.addedEvent.forTarget(this);
final EventStream<Event> onAddedToStage #
EventStream<Event> get onAddedToStage => DisplayObject.addedToStageEvent.forTarget(this);
final EventStream<EnterFrameEvent> onEnterFrame #
EventStream<EnterFrameEvent> get onEnterFrame => DisplayObject.enterFrameEvent.forTarget(this);
final EventStream<ExitFrameEvent> onExitFrame #
EventStream<ExitFrameEvent> get onExitFrame => DisplayObject.exitFrameEvent.forTarget(this);
final EventStream<KeyboardEvent> onKeyDown #
EventStream<KeyboardEvent> get onKeyDown => InteractiveObject.keyDownEvent.forTarget(this);
final EventStream<KeyboardEvent> onKeyUp #
EventStream<KeyboardEvent> get onKeyUp => InteractiveObject.keyUpEvent.forTarget(this);
final EventStream<MouseEvent> onMouseClick #
EventStream<MouseEvent> get onMouseClick => InteractiveObject.mouseClickEvent.forTarget(this);
final EventStream<MouseEvent> onMouseContextMenu #
EventStream<MouseEvent> get onMouseContextMenu => InteractiveObject.mouseContextMenu.forTarget(this);
final EventStream<MouseEvent> onMouseDoubleClick #
EventStream<MouseEvent> get onMouseDoubleClick => InteractiveObject.mouseDoubleClickEvent.forTarget(this);
final EventStream<MouseEvent> onMouseDown #
EventStream<MouseEvent> get onMouseDown => InteractiveObject.mouseDownEvent.forTarget(this);
final EventStream<MouseEvent> onMouseMiddleClick #
EventStream<MouseEvent> get onMouseMiddleClick => InteractiveObject.mouseMiddleClickEvent.forTarget(this);
final EventStream<MouseEvent> onMouseMiddleDown #
EventStream<MouseEvent> get onMouseMiddleDown => InteractiveObject.mouseMiddleDownEvent.forTarget(this);
final EventStream<MouseEvent> onMouseMiddleUp #
EventStream<MouseEvent> get onMouseMiddleUp => InteractiveObject.mouseMiddleUpEvent.forTarget(this);
final EventStream<MouseEvent> onMouseMove #
EventStream<MouseEvent> get onMouseMove => InteractiveObject.mouseMoveEvent.forTarget(this);
final EventStream<MouseEvent> onMouseOut #
EventStream<MouseEvent> get onMouseOut => InteractiveObject.mouseOutEvent.forTarget(this);
final EventStream<MouseEvent> onMouseOver #
EventStream<MouseEvent> get onMouseOver => InteractiveObject.mouseOverEvent.forTarget(this);
final EventStream<MouseEvent> onMouseRightClick #
EventStream<MouseEvent> get onMouseRightClick => InteractiveObject.mouseRightClickEvent.forTarget(this);
final EventStream<MouseEvent> onMouseRightDown #
EventStream<MouseEvent> get onMouseRightDown => InteractiveObject.mouseRightDownEvent.forTarget(this);
final EventStream<MouseEvent> onMouseRightUp #
EventStream<MouseEvent> get onMouseRightUp => InteractiveObject.mouseRightUpEvent.forTarget(this);
final EventStream<MouseEvent> onMouseRollOut #
EventStream<MouseEvent> get onMouseRollOut => InteractiveObject.mouseRollOutEvent.forTarget(this);
final EventStream<MouseEvent> onMouseRollOver #
EventStream<MouseEvent> get onMouseRollOver => InteractiveObject.mouseRollOverEvent.forTarget(this);
final EventStream<MouseEvent> onMouseUp #
EventStream<MouseEvent> get onMouseUp => InteractiveObject.mouseUpEvent.forTarget(this);
final EventStream<MouseEvent> onMouseWheel #
EventStream<MouseEvent> get onMouseWheel => InteractiveObject.mouseWheelEvent.forTarget(this);
final EventStream<Event> onRemoved #
EventStream<Event> get onRemoved => DisplayObject.removedEvent.forTarget(this);
final EventStream<Event> onRemovedFromStage #
EventStream<Event> get onRemovedFromStage => DisplayObject.removedFromStageEvent.forTarget(this);
final EventStream<RenderEvent> onRender #
EventStream<RenderEvent> get onRender => DisplayObject.renderEvent.forTarget(this);
final EventStream<TextEvent> onTextInput #
EventStream<TextEvent> get onTextInput => InteractiveObject.textInputEvent.forTarget(this);
final EventStream<TouchEvent> onTouchBegin #
EventStream<TouchEvent> get onTouchBegin => InteractiveObject.touchBeginEvent.forTarget(this);
final EventStream<TouchEvent> onTouchCancel #
EventStream<TouchEvent> get onTouchCancel => InteractiveObject.touchCancelEvent.forTarget(this);
final EventStream<TouchEvent> onTouchEnd #
EventStream<TouchEvent> get onTouchEnd => InteractiveObject.touchEndEvent.forTarget(this);
final EventStream<TouchEvent> onTouchMove #
EventStream<TouchEvent> get onTouchMove => InteractiveObject.touchMoveEvent.forTarget(this);
final EventStream<TouchEvent> onTouchOut #
EventStream<TouchEvent> get onTouchOut => InteractiveObject.touchOutEvent.forTarget(this);
final EventStream<TouchEvent> onTouchOver #
EventStream<TouchEvent> get onTouchOver => InteractiveObject.touchOverEvent.forTarget(this);
final DisplayObjectContainer parent #
DisplayObjectContainer get parent => _parent;
num pivotX #
num get pivotX => _pivotX;
set pivotX(num value) {
 if (value is num) _pivotX = value;
 _transformationMatrixRefresh = true;
}
num pivotY #
num get pivotY => _pivotY;
set pivotY(num value) {
 if (value is num) _pivotY = value;
 _transformationMatrixRefresh = true;
}
final DisplayObject root #
DisplayObject get root {
 DisplayObject currentObject = this;
 while (currentObject._parent != null)
   currentObject = currentObject._parent;
 return currentObject;
}
num rotation #
num get rotation => _rotation;
set rotation(num value) {
 if (value is num) _rotation = value;
 _transformationMatrixRefresh = true;
}
num scaleX #
num get scaleX => _scaleX;
set scaleX(num value) {
 if (value is num) _scaleX = value;
 _transformationMatrixRefresh = true;
}
num scaleY #
num get scaleY => _scaleY;
set scaleY(num value) {
 if (value is num) _scaleY = value;
 _transformationMatrixRefresh = true;
}
Shadow shadow #
Shadow get shadow => _shadow;
set shadow(Shadow value) {
 _shadow = value;
}
num skewX #
num get skewX => _skewX;
set skewX(num value) {
 if (value is num) _skewX = value;
 _transformationMatrixRefresh = true;
}
num skewY #
num get skewY => _skewY;
set skewY(num value) {
 if (value is num) _skewY = value;
 _transformationMatrixRefresh = true;
}
final Stage stage #
Stage get stage {
 DisplayObject root = this.root;
 return (root is Stage) ? root : null;
}
int startPosition #
Specifies what the first frame to play in this movieclip, or the only frame to display if mode is SINGLE_FRAME.
int startPosition = 0
bool tabChildren #
bool get tabChildren => _tabChildren;
void set tabChildren(bool value) { _tabChildren = value; }
Timeline timeline #
The Timeline that is associated with this MovieClip. This is created automatically when the MovieClip instance is initialized.
Timeline timeline
final int totalFrames #
Read-Only. The number of frames of the movieclip.
int get totalFrames {
 return timeline.duration.toInt();
}
final Matrix transformationMatrix #
Matrix get transformationMatrix {
 /*
 _transformationMatrix.identity();
 _transformationMatrix.translate(-_pivotX, -_pivotY);
 _transformationMatrix.scale(_scaleX, _scaleY);
 _transformationMatrix.rotate(_rotation);
 _transformationMatrix.translate(_x, _y);
 */
 if (_transformationMatrixRefresh) {
   _transformationMatrixRefresh = false;
   num skewXrotation =  _skewX + _rotation;
   num skewYrotation =  _skewY + _rotation;
   num scaleX = _scaleX;
   num scaleY = _scaleY;
   num pivotX = _pivotX;
   num pivotY = _pivotY;
   // ToDo: https://bugzilla.mozilla.org/show_bug.cgi?id=661452
   if (scaleX > -0.0001 && scaleX < 0.0001) scaleX = (scaleX >= 0) ? 0.0001 : -0.0001;
   if (scaleY > -0.0001 && scaleY < 0.0001) scaleY = (scaleY >= 0) ? 0.0001 : -0.0001;
   if (skewXrotation == 0.0 && skewYrotation == 0.0) {
     _transformationMatrix.setTo(scaleX, 0.0, 0.0, scaleY, _x - pivotX * scaleX, _y - pivotY * scaleY);
   } else {
     num a, b, c, d;
     num cosX = cos(skewXrotation);
     num sinX = sin(skewXrotation);
     if (skewXrotation == skewYrotation) {
       a =   scaleX * cosX;
       b =   scaleX * sinX;
       c = - scaleY * sinX;
       d =   scaleY * cosX;
     } else {
       a =   scaleX * cos(skewYrotation);
       b =   scaleX * sin(skewYrotation);
       c = - scaleY * sinX;
       d =   scaleY * cosX;
     }
     num tx =  _x - (pivotX * a + pivotY * c);
     num ty =  _y - (pivotX * b + pivotY * d);
     _transformationMatrix.setTo(a, b, c, d, tx, ty);
   }
 }
 return _transformationMatrix;
}
var userData #
Gets or sets user-defined data associated with the display object.
dynamic userData = null
bool visible #
bool get visible => _visible;
set visible(bool value) {
 if (value is bool) _visible = value;
}
num width #
num get width => getBoundsTransformed(this.transformationMatrix).width;
void set width(num value) {
 this.scaleX = 1;
 num normalWidth = this.width;
 this.scaleX = (normalWidth != 0.0) ? value / normalWidth : 1.0;
}
num x #
num get x => _x;
set x(num value) {
 if (value is num) _x = value;
 _transformationMatrixRefresh = true;
}
num y #
num get y => _y;
set y(num value) {
 if (value is num) _y = value;
 _transformationMatrixRefresh = true;
}
Methods
void addChild(DisplayObject child) #
void addChild(DisplayObject child) {
 addChildAt(child, _children.length);
}
void addChildAt(DisplayObject child, int index) #
void addChildAt(DisplayObject child, int index) {
 if (index < 0 || index > _children.length) {
   throw new ArgumentError("Error #2006: The supplied index is out of bounds.");
 }
 if (child == this) {
   throw new ArgumentError("Error #2024: An object cannot be added as a child of itself.");
 }
 if (child.parent == this) {
   _children.remove(child);
   if (index > _children.length) index -= 1;
   _children.insert(index, child);
 } else {
   child.removeFromParent();
   for(var ancestor = this; ancestor != null; ancestor = ancestor.parent) {
     if (ancestor == child) {
       throw new ArgumentError("Error #2150: An object cannot be added as "
           "a child to one of it's children (or children's children, etc.).");
     }
   }
   _children.insert(index, child);
   child._parent = this;
   child.dispatchEvent(new Event(Event.ADDED, true));
   if (this.stage != null) {
     _dispatchEventDescendants(child, new Event(Event.ADDED_TO_STAGE));
   }
 }
}
StreamSubscription<Event> addEventListener(String eventType, EventListener eventListener, {bool useCapture: false, int priority: 0}) #
StreamSubscription<Event> addEventListener(String eventType, EventListener eventListener, {
 bool useCapture: false, int priority: 0 }) {
 return this.on(eventType)._subscribe(eventListener, useCapture, priority);
}
void addTo(DisplayObjectContainer parent) #
void addTo(DisplayObjectContainer parent) {
 parent.addChild(this);
}
void advance(num deltaTime) #
Advances timelines and places children depending on the currentframe NOTE: automatically called by .render()
void advance(num deltaTime) {
 _advanceTime(deltaTime);
 _updateTimeline();
}
void applyCache(int x, int y, int width, int height, {bool debugBorder: false}) #
void applyCache(int x, int y, int width, int height, {bool debugBorder: false}) {
 var pixelRatio = Stage.autoHiDpi ? _devicePixelRatio : 1.0;
 if (_cacheTexture == null) {
   _cacheTexture = new RenderTexture(width, height, true, Color.Transparent, pixelRatio);
 } else {
   _cacheTexture.resize(width, height);
 }
 _cacheRectangle = new Rectangle(x, y, width, height);
 _cacheDebugBorder = debugBorder;
 refreshCache();
}
bool contains(DisplayObject child) #
bool contains(DisplayObject child) {
 while(child != null) {
   if (child == this) return true;
   child = child.parent;
 }
 return false;
}
void dispatchEvent(Event event) #
void dispatchEvent(Event event) {
 List<DisplayObject> ancestors = null;
 if (event.captures || event.bubbles) {
   for(DisplayObject ancestor = parent; ancestor != null; ancestor = ancestor.parent) {
     if(ancestor._hasPropagationEventListeners(event)) {
       if (ancestors == null) ancestors = [];
       ancestors.add(ancestor);
     }
   }
 }
 if (ancestors != null && event.captures) {
   for(int i = ancestors.length - 1 ; i >= 0; i--) {
     ancestors[i]._dispatchEventInternal(event, this, EventPhase.CAPTURING_PHASE);
     if (event.stopsPropagation) return;
   }
 }
 _dispatchEventInternal(event, this, EventPhase.AT_TARGET);
 if (event.stopsPropagation) return;
 if (ancestors != null && event.bubbles) {
   for(int i = 0; i < ancestors.length; i++) {
     ancestors[i]._dispatchEventInternal(event, this, EventPhase.BUBBLING_PHASE);
     if (event.stopsPropagation) return;
   }
 }
}
Rectangle getBounds(DisplayObject targetSpace) #
Rectangle getBounds(DisplayObject targetSpace) {
 Rectangle returnRectangle = new Rectangle.zero();
 Matrix matrix = (targetSpace == null) ? transformationMatrix : transformationMatrixTo(targetSpace);
 return (matrix != null) ? getBoundsTransformed(matrix, returnRectangle) : returnRectangle;
}
Rectangle getBoundsTransformed(Matrix matrix, [Rectangle returnRectangle]) #
Rectangle getBoundsTransformed(Matrix matrix, [Rectangle returnRectangle]) {
 
 if (returnRectangle == null)
   returnRectangle = new Rectangle.zero();
 
 super.getBoundsTransformed(matrix, returnRectangle);
 
 if (_graphics != null) {
   returnRectangle = _graphics._getBoundsTransformed(matrix).union(returnRectangle);
 }
 
 return returnRectangle;
}
dynamic getChildAt(int index) #
dynamic getChildAt(int index) {
 if (index < 0 || index >= _children.length) {
   throw new ArgumentError("Error #2006: The supplied index is out of bounds.");
 }
 return _children[index];
}
dynamic getChildByName(String name) #
dynamic getChildByName(String name) {
 for(int i = 0; i < _children.length; i++) {
   DisplayObject child = _children[i];
   if (child.name == name) return child;
 }
 return null;
}
int getChildIndex(DisplayObject child) #
int getChildIndex(DisplayObject child) {
 return _children.indexOf(child);
}
Point globalToLocal(Point globalPoint) #
Point globalToLocal(Point globalPoint) {
 _tmpMatrix.identity();
 for(var current = this; current != null; current = current._parent) {
   _tmpMatrix.concat(current.transformationMatrix);
 }
 _tmpMatrix.invert();
 return _tmpMatrix.transformPoint(globalPoint);
}
void gotoAndPlay(positionOrLabel) #
Advances this movie clip to the specified position or label and sets paused to false.
void gotoAndPlay(dynamic positionOrLabel) {
 paused = false;
 _goto(positionOrLabel);
}
void gotoAndStop(positionOrLabel) #
Advances this movie clip to the specified position or label and sets paused to true.
void gotoAndStop(dynamic positionOrLabel) {
 paused = true;
 _goto(positionOrLabel);
}
bool hasEventListener(String eventType) #
bool hasEventListener(String eventType) {
 var eventStreams = _eventStreams;
 if (eventStreams == null) return false;
 var eventStream = eventStreams[eventType];
 if (eventStream == null) return false;
 return eventStream.hasSubscriptions;
}
DisplayObject hitTestInput(num localX, num localY) #
DisplayObject hitTestInput(num localX, num localY) {
 
 DisplayObject target = null;
 
 if (this.hitArea != null) {
   
   var matrix = this.transformationMatrixTo(this.hitArea);
   if (matrix != null) {
     double hitAreaX = localX * matrix.a + localY * matrix.c + matrix.tx;
     double hitAreaY = localX * matrix.b + localY * matrix.d + matrix.ty;
     
     if (this.hitArea.hitTestInput(hitAreaX, hitAreaY) != null) {
       target = this;
     }
   }
 } else {
 
   target = super.hitTestInput(localX, localY);
   
   if (target == null && _graphics != null) {
     if (_graphics._hitTestInput(localX, localY)) {
       target = this;
     }
   } 
 }
 
 return target;
}
bool hitTestObject(DisplayObject other) #
bool hitTestObject(DisplayObject other) {
 var stage1 = this.stage;
 var stage2 = other.stage;
 if (stage1 == null || stage2 == null || stage1 != stage2) return false;
 var rect1 = this.getBounds(stage1);
 var rect2 = other.getBounds(stage2);
 return rect1.intersects(rect2);
}
bool hitTestPoint(num x, num y, [bool shapeFlag = false]) #
bool hitTestPoint(num x, num y, [bool shapeFlag = false]) {
 var stage = this.stage;
 if (stage == null) return false;
 if (shapeFlag) {
   var matrix = stage.transformationMatrixTo(this);
   if (matrix == null) return false;
   var stagePoint = new Point(x, y);
   var localPoint = matrix.transformPoint(stagePoint);
   return this.hitTestInput(localPoint.x, localPoint.y) != null;
 } else {
   var rect = this.getBounds(stage);
   return rect.contains(x, y);
 }
}
bool isVisible() #
Returns true or false indicating whether the display object would be visible if drawn to a canvas. This does not account for whether it would be visible within the boundaries of the stage. NOTE: This method is mainly for internal use, though it may be useful for advanced uses. @method isVisible @return {Boolean} Boolean indicating whether the display object would be visible if drawn to a canvas
bool isVisible() {
 // children are placed in draw, so we can't determine if we have content.
 return !!(this.visible && this.alpha > 0 && this.scaleX != 0 && this.scaleY != 0);
}
Point localToGlobal(Point localPoint) #
Point localToGlobal(Point localPoint) {
 _tmpMatrix.identity();
 for(var current = this; current != null; current = current._parent) {
   _tmpMatrix.concat(current.transformationMatrix);
 }
 return _tmpMatrix.transformPoint(localPoint);
}
EventStream<Event> on(String eventType) #
EventStream<Event> on(String eventType) {
 var eventStreams = _eventStreams;
 if (eventStreams == null) {
   eventStreams = new Map<String, EventStream>();
   _eventStreams = eventStreams;
 }
 var eventStream = eventStreams[eventType];
 if (eventStream == null) {
   eventStream = new EventStream._internal(this, eventType);
   eventStreams[eventType] = eventStream;
 }
 return eventStream;
}
void play() #
Sets paused to false.
void play() {
 paused = false;
}
void refreshCache() #
void refreshCache() {
 if (_cacheTexture == null) return;
 var x = _cacheRectangle.x;
 var y = _cacheRectangle.y;
 var width = _cacheRectangle.width;
 var height = _cacheRectangle.height;
 var canvas = _cacheTexture.canvas;
 var matrix = _cacheTexture.quad.drawMatrix..translate(-x, -y);
 var renderContext = new RenderContextCanvas(canvas, Color.Transparent);
 var renderState = new RenderState(renderContext, matrix);
 renderContext.clear();
 render(renderState);
 if (_filters != null) {
   var cacheBitmapData = new BitmapData.fromRenderTextureQuad(_cacheTexture.quad);
   var bounds = this.getBoundsTransformed(_identityMatrix)..offset(-x, -y);
   for(var filter in _filters) {
     var filterOverlap = filter.overlap;
     var filterBounds = bounds.clone();
     filterBounds.offset(filterOverlap.x, filterOverlap.y);
     filterBounds.inflate(filterOverlap.width, filterOverlap.height);
     filter.apply(cacheBitmapData, filterBounds.align());
   }
 }
 if (_cacheDebugBorder) {
   canvas.context2D
       ..setTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
       ..lineWidth = 1
       ..lineJoin = "miter"
       ..lineCap = "butt"
       ..strokeStyle = "#FF00FF"
       ..strokeRect(0.5, 0.5, canvas.width - 1, canvas.height - 1);
 }
 _cacheTexture.update();
}
void removeCache() #
void removeCache() {
 if (_cacheTexture != null) {
   _cacheTexture.dispose();
   _cacheTexture = null;
 }
}
void removeChild(DisplayObject child) #
void removeChild(DisplayObject child) {
 int childIndex = _children.indexOf(child);
 if (childIndex == -1) {
   throw new ArgumentError(
       "Error #2025: The supplied DisplayObject must be a child of the caller.");
 }
 removeChildAt(childIndex);
}
void removeChildAt(int index) #
void removeChildAt(int index) {
 if (index < 0 || index >= _children.length) {
   throw new ArgumentError("Error #2006: The supplied index is out of bounds.");
 }
 DisplayObject child = _children[index];
 child.dispatchEvent(new Event(Event.REMOVED, true));
 if (this.stage != null) {
   _dispatchEventDescendants(child, new Event(Event.REMOVED_FROM_STAGE));
 }
 child._parent = null;
 _children.removeAt(index);
}
void removeChildren([int beginIndex = 0, int endIndex = 0x7fffffff]) #
void removeChildren([int beginIndex = 0, int endIndex = 0x7fffffff]) {
 var length = _children.length;
 if (length == 0) return;
 if (endIndex == 0x7fffffff) {
   endIndex = length - 1;
 }
 if (beginIndex < 0 || endIndex < 0 || beginIndex >= length || endIndex >= length) {
   throw new ArgumentError("Error #2006: The supplied index is out of bounds.");
 }
 for(int i = beginIndex; i <= endIndex; i++) {
   if (beginIndex >= _children.length) break;
   removeChildAt(beginIndex);
 }
}
void removeEventListener(String eventType, EventListener eventListener, {bool useCapture: false}) #
void removeEventListener(String eventType, EventListener eventListener, {
 bool useCapture: false }) {
 this.on(eventType)._unsubscribe(eventListener, useCapture);
}
void removeEventListeners(String eventType) #
void removeEventListeners(String eventType) {
 this.on(eventType).cancelSubscriptions();
}
void removeFromParent() #
void removeFromParent() {
 if (_parent != null)
   _parent.removeChild(this);
}
void render(RenderState renderState) #
Draws the display object into the specified context ignoring it's visible, alpha, shadow, and transform. Returns true if the draw was handled (useful for overriding functionality). NOTE: This method is mainly for internal use, though it may be useful for advanced uses. @param {CanvasRenderingContext2D} ctx The canvas 2D context object to draw into. @param {Boolean} ignoreCache Indicates whether the draw operation should ignore any current cache. For example, used for drawing the cache (to prevent it from simply drawing an existing cache back into itself).
void render(RenderState renderState) {
 advance(renderState.deltaTime);
 super.render(renderState);
}
void setChildIndex(DisplayObject child, int index) #
void setChildIndex(DisplayObject child, int index) {
 if (index < 0 || index >= _children.length) {
   throw new ArgumentError("Error #2006: The supplied index is out of bounds.");
 }
 int oldIndex = getChildIndex(child);
 if (oldIndex == -1) {
   throw new ArgumentError("Error #2025: The supplied DisplayObject must be a child of the caller.");
 }
 _children.removeAt(oldIndex);
 _children.insert(index, child);
}
void setTransform(num x, num y, [num scaleX, num scaleY, num rotation, num skewX, num skewY, num pivotX, num pivotY]) #
void setTransform(num x, num y, [num scaleX, num scaleY, num rotation, num skewX, num skewY, num pivotX, num pivotY]) {
 if (x is num) _x = x;
 if (y is num) _y = y;
 if (scaleX is num) _scaleX = scaleX;
 if (scaleY is num) _scaleY = scaleY;
 if (rotation is num) _rotation = rotation;
 if (skewX is num) _skewX = skewX;
 if (skewY is num) _skewY = skewY;
 if (pivotX is num) _pivotX = pivotX;
 if (pivotY is num) _pivotY = pivotY;
 _transformationMatrixRefresh = true;
}
void sortChildren(Function compareFunction) #
void sortChildren(Function compareFunction) {
 _children.sort(compareFunction);
}
dynamic startDrag([bool lockCenter = false, Rectangle bounds = null]) #
startDrag([bool lockCenter = false, Rectangle bounds = null]) {
 
 Mouse._dragSprite = this;
 Mouse._dragSpriteBounds = bounds;
 
 if (lockCenter) {
   Mouse._dragSpriteCenter = this.getBoundsTransformed(_identityMatrix).center;
 } else {
   var mp = this.mousePosition;
   Mouse._dragSpriteCenter = (mp != null) ? mp : new Point.zero();
 }
 _updateDrag();
}
void stop() #
Sets paused to true.
void stop() {
 paused = true;
}
dynamic stopDrag() #
stopDrag() {
 
 if (Mouse._dragSprite == this) {
   Mouse._dragSprite = null;
   Mouse._dragSpriteCenter = null;
   Mouse._dragSpriteBounds = null;
 }
}
void swapChildren(DisplayObject child1, DisplayObject child2) #
void swapChildren(DisplayObject child1, DisplayObject child2) {
 int index1 = getChildIndex(child1);
 int index2 = getChildIndex(child2);
 if (index1 == -1 || index2 == -1) {
   throw new ArgumentError("Error #2025: The supplied DisplayObject must be a child of the caller.");
 }
 swapChildrenAt(index1, index2);
}
void swapChildrenAt(int index1, int index2) #
void swapChildrenAt(int index1, int index2) {
 DisplayObject child1 = getChildAt(index1);
 DisplayObject child2 = getChildAt(index2);
 _children[index1] = child2;
 _children[index2] = child1;
}
String toString() #
Returns a string representation of this object. @return {String} a string representation of the instance.
String toString() {
 return "[MovieClip (name=$name)]";
}
Matrix transformationMatrixTo(DisplayObject targetSpace) #
Matrix transformationMatrixTo(DisplayObject targetSpace) {
 if (targetSpace == _parent) {
   return this.transformationMatrix.clone();
 }
 if (targetSpace != null && targetSpace._parent == this) {
   return targetSpace.transformationMatrix.cloneInvert();
 }
 //------------------------------------------------
 Matrix resultMatrix = new Matrix.fromIdentity();
 DisplayObject resultObject = this;
 while(resultObject != targetSpace && resultObject._parent != null) {
   resultMatrix.concat(resultObject.transformationMatrix);
   resultObject = resultObject._parent;
 }
 if (targetSpace == null && resultObject != null) {
   resultMatrix.concat(resultObject.transformationMatrix);
   resultObject = null;
 }
 if (resultObject == targetSpace)
   return resultMatrix;
 //------------------------------------------------
 Matrix targetMatrix = new Matrix.fromIdentity();
 DisplayObject targetObject = targetSpace;
 while(targetObject != this && targetObject._parent != null) {
   targetMatrix.concat(targetObject.transformationMatrix);
   targetObject = targetObject._parent;
 }
 targetMatrix.invert();
 if (targetObject == this) {
   return targetMatrix;
 }
 if (targetObject != resultObject) {
   return null;
 }
 resultMatrix.concat(targetMatrix);
 return resultMatrix;
}