Rotate a drawn rectangle in flex - apache-flex

i wrote the following code for drawing a rotate rectangle
var s:UIComponent = new UIComponent();
s.graphics.lineStyle(1, 0x0000FF);
s.graphics.drawRect(50, 50, 200, 200);
s.rotation = 30;
template.addChild(s);
where template is a canvas. Its rotate nicely but the problem is the position is not in right place. i.e. it is not in (50,50) after rotate. How can i solve this problem?
Thanks in advance.

What you're seeing is the default rotation around the origin in Flex (in your case the X,Y coordinates of 50,50) I am assuming that you want to rotate around the center (as I recently had to do). There is the jury rig way to do it, by adjusting the origin point based on rotation angle. Then there is the rotate effect:
import mx.effects.Rotate;
var s:UIComponent = new UIComponent();
var rotator:Rotate = new Rotate(s);
s.graphics.lineStyle(1, 0x0000FF);
s.graphics.drawRect(50, 50, 200, 200);
rotator.angleFrom = 0;
rotator.angleTo = 30;
rotator.originX = s.width/2;
rotator.originY = s.height/2;
template.addChild(s);
rotator.play();
Now I've noticed some problems with this that required me to set the width and height of the rotated object again after the play() method, but other than that I get the ideal rotation situation.
Another downside to this is that it's an effect, which means it visually rotates the object. I will post back when I correct that, if you don't want to see the object rotate.
The Answer is duration
just by adding rotator.duration = 1 before play it happens so quick the user won't see it. 1 being 1 millisecond. I tried 0, but that resulted in no rotation occurring. Obviously if you want to see the effect in action you can increase that length of time by using any value in milliseconds.

Related

How to disable linear filtering for drawImage on canvas in javafx

I'm trying to draw scaled image on canvas in javafx. Using this code:
Image image = ...;
canvas.setWidth(scale * width);
canvas.setHeight(scale * height);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(image, 0, 0, scale * width, scale * height);
// this gives same result
// gc.scale(scale, scale);
// gc.drawImage(editableImage, 0, 0, width, height);
It works really fast but makes blurred images like this:
This is not what I'd like to see. Instead I want to get this picture:
Which can be drawn by manually setting each pixel color with such code:
PixelReader reader = image.getPixelReader();
PixelWriter writer = gc.getPixelWriter();
for (int y = 0; y < scale * height; ++y) {
for (int x = 0; x < scale * width; ++x) {
writer.setArgb(x, y, reader.getArgb(x / scale, y / scale));
}
}
But I cannot use this approach as it's too slow. It took couple of seconds to draw 1Kb image scaled 8 times. So I ask if there's any way to disable this blurry effect for drawing on canvas?
UPD 10/07/2019:
Looks like the issue is fixed! Now GraphicsContext should have property "image smoothing" controlling this behavior.
INITIAL ANSWER
I guess I've found answer to my question. As this issue says that there's no way to specify filtering options in graphics context.
Description:
When drawing an image in a GraphicsContext using the drawImage()
method to enlarge a small image to a larger canvas, the image is being
interpolated (possibly using a bilinear or bicubic algorithm). But
there are times like when rendering color maps (temperature,
zooplancton, salinity, etc.) or some geographical data (population
concentration, etc.) where we want to have no interpolation at all
(ie: use the nearest neighbor algorithm instead) in order to represent
accurate data and shapes.
In Java2D, this is possible by setting the appropriate
RenderingHints.KEY_RENDERING on the Graphics2D at hand. Currently on
JavaFX's GraphicsContext there is no such way to specify how the image
is to be interpolated.
The same applies when shrinking images too.
This could be expanded to support a better form of smoothing for the
"smooth" value that is available in both Image and ImageView and that
does not seem to work very well currently (at least on Windows).
The issue was created in 2013 but it's still untouched so unlikely it will be resolved soon.

Dynamically change plane height in babylonjs

I created a plane by using
this.plane = BABYLON.MeshBuilder.CreatePlane("plane", { width: 0.5, height: 10 }, scene, true);
and then I try to modify the plane height in rendering, but the height is not changed.
I think you are looking for scaling. Here is the link to Babylon.js Scaling. Essentially, you do
objectName.scaling.x = 1.50 //This is a scaling multiplier (you can substitute x, y, and z)
//Or, if you want to scale in more than one direction, you can use a vector3
objectName.scaling = new Babylon.Vector3(1.5,.5, 2)
This should let you dynamically change the dimensions of your object. If you wanted the make the change visibly noticeable (instead of jumping straight to the correct size) you could also add an animation to it.

How to move an object along a spline or sine function in Flex 3

I am trying to create a similar effect to what is used in CityVille for dropping coins and experience icons, they do a custom move animation and it first moves a little bit up and then down. It looks like it is following a spline or a sine function.
The Move effect in flex 3 only moves linearly.
Any help?
Use a tweening library such as Actuate http://code.google.com/p/actuate/
It lets you animate an object along a bezier curve or custom motion path like this:
var xPath:MotionPath = MotionPath.bezier (200, 20).line (400);
var yPath:MotionPath = MotionPath.bezier (0, 300).line (0);
Actuate.motionPath (MySprite, 1, { x: xPath, y: yPath } );
A very similar library is eaze
http://code.google.com/p/eaze-tween/
and it's mxml friendly wrapper:
http://code.google.com/p/eazefx/
You should be looking at Tweens instead of Moves. An example could be:
import mx.transitions.easing.*;
import mx.transitions.Tween;
new Tween(myMC, ‘_x’, Regular.easeOut, myMC._x, myMC._x + 300, 30);
new Tween(myMC, ‘_y’, Regular.easeIn, myMC._y, myMC._y + 300, 30);
Code is random Google result, so I post no guarantees. Also for myself I would prefer a tween engine like TweenLite: http://www.greensock.com/tweenlite/

how to do 3D rotation around center in AS3 using matrix3D?

I am trying to rotate a Sprite in three dimensions around its centerpoint, and I am struggling to understand some of the behavior of matrix3D.
Ive overridden the set rotationX, rotationY, and rotationZ methods of the Sprite as follows:
override public function set rotationX (_rotationX:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationX, Vector3D.X_AXIS);
this.transform.matrix3D.prependRotation(_rotationX, Vector3D.X_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
override public function set rotationY (_rotationY:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationY, Vector3D.Y_AXIS);
this.transform.matrix3D.prependRotation(_rotationY, Vector3D.Y_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
override public function set rotationZ (_rotationZ:Number) : void {
this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
this.transform.matrix3D.prependRotation(-this.rotationZ, Vector3D.Z_AXIS);
this.transform.matrix3D.prependRotation(_rotationZ, Vector3D.Z_AXIS);
this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);
}
I am using prependTranslation to correct the centerpoint of the rotation, and the first prependRotation to cancel out any previously-applied rotation.
Testing it out, rotationX works exactly as expected, and the Sprite rotates around its horizontal axis.
rotationY and rotationZ also appear to work fine. However, there is one problem: whenever rotationY or rotationZ are set, all of the other rotation values change as well. This is not a problem with rotationX -- if I set rotationX, nothing else changes. But if I set rotationY or rotationZ all the rotation values change, which is a problem for my app (which is trying to save and restore values).
I think I am just lacking some understanding about what is going on with matrix3D. How can I implement this so there is no interdependence between the values?
Another easy solution is to add the object and center it within a container sprite and do the 3D transformations on the containing sprite.
I know nothing about AS3 etc. But just looking at your code, I wonder why you translate on the z-axis using what I understand to be x and y values (width and height). Shouldn't the z-axis be translated using something like "depth"?
This is very simple, you can try use the following code:
var matrix3d:Matrix3D = s.transform.matrix3D;
matrix3d.appendRotation( -1, Vector3D.Z_AXIS , new Vector3D( 390, 360, 0 ) );
while s is your sprite, the third parameter, Vector3D indicate your sprite's center position.
The Above code will make the sprite s rotate more -1 degree.

rotating centered content

Ok, so I've been trying to get this concept to work for the day now and have had zero luck. I am not so good with math, so any help will be appreciated. I am trying to rotate a centered container from it's center. The problem with this code is when I use the rotatePicture method, it doesn't rotate from the center, instead it rotates from the box's top-left corner. Here's the code...
import mx.effects.Rotate;
private function init():void
{
calculateCoordinates();
}
private function rotateBox():void
{
var m:Matrix = myBox.transform.matrix;
var centerX:Number = myBox.width / 2;
var centerY:Number = myBox.height / 2;
var centerPoint:Point = new Point(centerX, centerY);
var transformPoint:Point= m.transformPoint(centerPoint);
m.translate(-transformPoint.x, -transformPoint.y);
m.rotate(90 * Math.PI / 180);
m.translate(transformPoint.x, transformPoint.y);
myBox.transform.matrix = m;
this.callLater(calculateCoordinates);
//calculateCoordinates();
}
private function calculateCoordinates():void
{
var x : Number = (myBox.parent.width - myBox.width) / 2;
x = x < 0 ? 0 : x;
var y : Number = (myBox.parent.height - myBox.height) / 2;
y = y < 0 ? 0 : y;
myBox.move(x, y);
}
Ok, this was a bit tricky and i'm working out a couple of details, but in case anyone had a similar issue, I found the general answer. Just took a movie break to refresh the brain...
I had to place a variable for how many turns the canvas had rotated which was easy since I was restricting the degrees to only 90. Then I place in a switch statement that tested the turns variable and recalculated the (x,y) coordinates based off of the turns. Since I knew that the Rotate class would create a cooler effect and end with the same result, I ended up using that instead.
Cheers!
I don't know what your background is, but in my experience this is a classic case of "out-thinking yourself".
You've written quite a bit of code to do something that is actually native to the Flash display API's.
Since you seem to be using Flex I'll just tell you that the simple way to achieve this is to dynamically reposition your display clip contents so that the center of your contents is at the 0,0 point of your clip.
This gets harder the more content you have, but if you just have something like an image or a button or what have you, it's really easy to just calculate the height and width, then divide by 2 and subtract.
Then the rotation property will work just fine.
In Flash it's even easier because you can just make a new clip, bind your class to the clip, and place all yours contents in the Flash authoring tool positioned properly for rotation to work as expected.
Yeah, what Back2Dos said.
Personally, I'd wrap the container in another sprite, position it so its center is at (0,0) in that sprites coordinate space, and then just rotate the sprite ... it's simple and robust ...
I'd like to use <s:Rotate> to rotate center. Hope useful to you.

Resources