Rotating with matrix transform

Ask a Question related to Macromedia Flex General Discussion, Design and Development.

  1. #1

    Default Rotating with matrix transform

    Hi all,
    I am trying to rotate a subclass of UIComponent, but am running into some
    issues. I am using a matrix transform to rotate the object around the center,
    but I am noticing that my object trails up and to the left. Its not noticeable
    at first, but after a while, the object seems to anchor around the 0,0 point of
    the main application. My code is available here:

    [url]http://flash.pastebin.com/m610b0f9f[/url]

    Would love some guidance!

    Thanks

    mdmave Guest

  2. Similar Questions and Discussions

    1. rotating about parent and "self" with transform.rotation?
      Hi is it possible to first rotate a model about its parent node and then rotate it about its own axis (or vice versa - that doesn't matter. The...
    2. transformation matrix
      Hey, I posted this before and don't think I got a response so I'm trying a second time. What do all of the letters in the beginGradientFill matrix...
    3. beginGradientFill() > matrix
      Hi, I'm having some difficulty understanding the matrix properties for the beginGradientFill method. So far (I think) I have found out the...
    4. Matrix multiplication?
      Hi I have a 21 * 21 matrix which I'd like to raise to the power of 50. Is it possible to do that in Perl? The matrix looks something like...
    5. Web Matrix and VS.NET
      Web Matrix and VS.NET have some things in common, but Web Matrix is aimed at those who code in their page rather than those who use the CodeBehind...
  3. #2

    Default Re: Rotating with matrix transform

    Nevermind, it turns out that the PDF docs are out of sync, the LiveDocs point to the correct zip files for MXML.
    ZeDav Guest

  4. #3

    Default Re: Rotating with matrix transform

    I'm guessing that the creep you're seeing on the spinner might be due to some
    rounding errors, but I can't say for certain looking at it casually.

    I've posted a slightly different approach that doesn't make use of any matrix
    transforms, but has exactly the same effect, while using the bulk of your code
    logic. It basically adds a shape, draws your spinner on the shape's graphics
    property and then rotates the shape. It's clean and simple without having to
    mess with any matrix transforms. This solution is based on
    [url]http://weblogs.macromedia.com/pent/archives/2007/10/component_class_2.html[/url].

    Reworked solution: [url]http://flash.pastebin.com/m610b0f9f[/url]

    TS

    VarioPegged Guest

  5. #4

    Default Re: Rotating with matrix transform

    Vario,
    Thanks so much for the reply! I ended up rewriting the component, and it seems
    to be working a lot better now. Check out the attached code.

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Spinner.mxml -->
    <mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="init()">
    <mx:Script>
    <![CDATA[

    import mx.effects.Rotate;
    import mx.effects.easing.Linear;
    import my.GraphicUtils;

    // private vars
    private var originX:Number;
    private var originY:Number;
    private var radius1:Number;
    private var radius2:Number;
    private var rotate:Rotate;

    // public properties
    public var spokes:int;
    public var spokeSize:Number;

    // private methods
    private function init():void {

    // center
    this.originX = this.width * .5;
    this.originY = this.height * .5;

    // radii
    this.radius1 = this.originX - this.spokeSize;
    this.radius2 = this.originX;

    draw();
    if(visible) rotate.play();
    }

    // public instance methods
    public function draw():void {
    var degrees:Number = 0;
    var radians:Number = 0;
    var angle:Number = 360 / this.spokes;

    var i:int;
    var a:Array = [];
    for(i = 0; i < this.spokes; i++) {
    degrees %= 360;
    radians = GraphicUtils.degreesToRadians(degrees);
    a.push([
    this.originX + (Math.sin(radians) * this.radius1), // X1
    this.originY + (-Math.cos(radians) * this.radius1), // Y1
    this.originX + (Math.sin(radians) * this.radius2), // X2
    this.originY + (-Math.cos(radians) * this.radius2) // Y2
    ]);
    degrees += angle;
    }
    var n:int = a.length;
    // draw background
    for (i = 0; i < n; i++) {
    graphics.lineStyle(2, 0x434343);
    graphics.moveTo(a[i][0], a[i][1]);
    graphics.lineTo(a[i][2], a[i][3]);
    }
    // draw white pieces
    var alpha:Number = 1;
    var pos:int = 0;
    for (i = 0; i < n; i++) {
    // TODO: make this user configable
    alpha = Math.max(1 - (i / (this.spokes * .5)), 0);

    // move backwards
    pos = (i == 0) ? 0 : n - i;

    graphics.lineStyle(2, 0xFFFFFF, alpha);
    graphics.moveTo(a[pos][0], a[pos][1]);
    graphics.lineTo(a[pos][2], a[pos][3]);

    }

    // rotate object
    rotate = new Rotate(this);
    rotate.duration = 850;
    rotate.easingFunction = Linear.easeNone;
    rotate.originX = this.originX;
    rotate.originY = this.originY;
    rotate.repeatCount = 0;

    }
    public function start():void { this.visible = true; }
    public function stop():void { this.visible = false; }
    public override function set visible(b:Boolean):void {
    super.visible = b;
    if (b) {
    if (rotate != null) rotate.play();
    } else {
    if (rotate != null) rotate.end();
    }
    }
    ]]>
    </mx:Script>
    </mx:UIComponent>

    mdmave Guest

  6. #5

    Default Re: Rotating with matrix transform

    Yes, it works fine for me now. Using the rotate effect is an elegant solution,
    however the only drawback currently is that the continuous rotation prevents it
    from behaving like a typical spinner. The rotation should be incremented by
    (360 / spokes) degrees resulting in a number of steps equal to the number of
    spokes.

    You'd be able to accomplish this by binding the angleFrom and angleTo
    properties of the rotate effect to a single bindable public property that you
    increment by (360 / spokes) degrees in an "enterframe" event handler. Something
    like this ...

    [Bindable] public var degrees:Number = 0;

    BindingUtils.bindProperty(rotate, "angleFrom", this, "degrees");
    BindingUtils.bindProperty(rotate, "angleTo", this, "degrees");

    ....
    private function handleEnterFrame(e:Event): void
    {
    rotate.end();
    degrees += 360 / spokes;
    rotate.play();
    }

    TS

    VarioPegged Guest

  7. #6

    Default Re: Rotating with matrix transform

    Hey thanks again! My very first bindable property :P I was never really sure
    when those were used.

    One thing I noticed, I had to add this in the handleEnterFrame function:

    private function handleEnterFrame(event:Event):void {
    rotate.end();
    degrees += 360 / this.spokes;
    degrees %= 360;
    rotate.play();
    }

    Otherwise the spinner would spiral out of control after a minute or two.
    Everything is going along fine and then it jumps out of control..

    Here is the full code



    <?xml version="1.0" encoding="utf-8"?>
    <!-- Spinner.mxml -->
    <mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="init()">
    <mx:Script>
    <![CDATA[
    import mx.binding.utils.BindingUtils;
    import mx.effects.Rotate;
    import mx.effects.easing.Linear;
    import com.yahoo.ap.utils.GraphicUtils;

    // private vars
    private var originX:Number;
    private var originY:Number;
    private var radius1:Number;
    private var radius2:Number;

    // public properties
    [Bindable] public var degrees:Number = 0;
    public var rotate:Rotate;
    public var spokes:int;
    public var spokeSize:Number;

    // private methods
    private function handleEnterFrame(event:Event):void {
    rotate.end();
    degrees += 360 / this.spokes;
    degrees %= 360;
    rotate.play();
    }
    private function init():void {

    // center
    this.originX = this.width * .5;
    this.originY = this.height * .5;

    // radii
    this.radius1 = this.originX - this.spokeSize;
    this.radius2 = this.originX;

    addListeners();


    draw();

    BindingUtils.bindProperty(rotate, "angleFrom", this, "degrees");
    BindingUtils.bindProperty(rotate, "angleTo", this, "degrees");


    if(visible) rotate.play();

    }

    // public instance methods
    public function addListeners():void {
    addEventListener(Event.ENTER_FRAME, handleEnterFrame);
    }
    public function draw():void {
    var degrees:Number = 0;
    var radians:Number = 0;

    var i:int;
    var a:Array = [];
    for(i = 0; i < this.spokes; i++) {
    degrees %= 360;
    radians = GraphicUtils.degreesToRadians(degrees);
    a.push([
    this.originX + (Math.sin(radians) * this.radius1), // X1
    this.originY + (-Math.cos(radians) * this.radius1), // Y1
    this.originX + (Math.sin(radians) * this.radius2), // X2
    this.originY + (-Math.cos(radians) * this.radius2) // Y2
    ]);
    degrees += 360 / this.spokes;
    }
    var n:int = a.length;
    // draw background
    for (i = 0; i < n; i++) {
    graphics.lineStyle(2, 0x434343);
    graphics.moveTo(a[i][0], a[i][1]);
    graphics.lineTo(a[i][2], a[i][3]);
    }
    // draw white pieces
    var alpha:Number = 1;
    var pos:int = 0;
    for (i = 0; i < n; i++) {
    // TODO: make this user configable
    alpha = Math.max(1 - (i / (this.spokes * .5)), 0);

    // move backwards
    pos = (i == 0) ? 0 : n - i;

    graphics.lineStyle(2, 0xFFFFFF, alpha);
    graphics.moveTo(a[pos][0], a[pos][1]);
    graphics.lineTo(a[pos][2], a[pos][3]);

    }

    // rotate object
    rotate = new Rotate(this);
    rotate.duration = 850;
    rotate.easingFunction = Linear.easeNone;
    rotate.angleFrom = degrees;
    rotate.angleTo = degrees += (360 / this.spokes);
    rotate.originX = this.originX;
    rotate.originY = this.originY;
    rotate.repeatCount = 0;

    }
    public function start():void { this.visible = true; }
    public function stop():void { this.visible = false; }
    public override function set visible(b:Boolean):void {
    super.visible = b;
    if (b) {
    if (rotate != null) rotate.play();
    } else {
    if (rotate != null) rotate.end();
    }
    }
    ]]>
    </mx:Script>
    </mx:UIComponent>

    mdmave Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139