Ask a Question related to Macromedia Flex General Discussion, Design and Development.
-
mdmave #1
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
-
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... -
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... -
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... -
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... -
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... -
ZeDav #2
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
-
VarioPegged #3
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
-
mdmave #4
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
-
VarioPegged #5
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
-
mdmave #6
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



Reply With Quote

