MasterMirror
MasterMirror

Reputation: 27

Rotating an image or shape in a Group in a HBox with JavaFX

enter image description here

I want to rotate an image in a Group and put the Group in an HBox without a noticeable "bouncing" effect. The image above is an example using JavaFX shapes instead of images but the end result is the same. The top HBox contains a rotating rectangle and it appears fine. The bottom HBox contains a rectangle and a circle in the same Group but rotating the rectangle causes a "bouncing" side-effect. Why is it bouncing? Here is my code:

public class RotateImage extends Application {

    @Override
    public void start( Stage primaryStage ) {
        Pane root = new Pane();
        HBox hbox = new HBox();
        hbox.setLayoutX( 10 );
        hbox.setLayoutY( 10 );
        Rectangle square = new Rectangle( 50, 50, Color.RED );
        hbox.getChildren().add( square );
        RotateTransition rt = new RotateTransition( Duration.millis( 1000 ), square );
        rt.setByAngle( 360 );
        rt.setCycleCount( Animation.INDEFINITE );
        rt.setInterpolator( Interpolator.LINEAR );
        rt.play();

        HBox hbox2 = new HBox();
        hbox2.setLayoutX( 10 );
        hbox2.setLayoutY( 100 );
        Rectangle square2 = new Rectangle( 50, 50, Color.RED );
        Circle circle2 = new Circle( 25, 25, 12.5, Color.BLUE );
        Group group = new Group( square2, circle2 );
        hbox2.getChildren().add( group );
        RotateTransition rt2 = new RotateTransition( Duration.millis( 1000 ), square2 );
        rt2.setByAngle( 360 );
        rt2.setCycleCount( Animation.INDEFINITE );
        rt2.setInterpolator( Interpolator.LINEAR );
        rt2.play();

        root.getChildren().addAll( hbox, hbox2 );
        Scene scene = new Scene( root, 100, 200, Color.BLACK );
        primaryStage.setScene( scene );
        primaryStage.setTitle( "Rotate Transition example" );
        primaryStage.show();
    }

    public static void main( String[] args ) {
        launch( args );
    }
}

Upvotes: 0

Views: 149

Answers (1)

c0der
c0der

Reputation: 18792

If you want a smooth rotation apply the rotation to the group, and not to one of its children.
Replace
RotateTransition rt2 = new RotateTransition( Duration.millis( 1000 ), square2 );

with
RotateTransition rt2 = new RotateTransition( Duration.millis( 1000 ), group );

If you must rotate a child within the group you can add a big "place holder" shape to the group. The role of the shape (a circle in the following example) is to have the group big enough so the square rotation does not change group bounds:

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class RotateImage extends Application {

    @Override
    public void start( Stage primaryStage ) {

        //big circle to keep group bounds big enough for the square to rotate inside
        Circle dummyCircle = new Circle(25,25,100, Color.BLACK );
        Rectangle square2 = new Rectangle( 50, 50, Color.RED );
        Circle circle2 = new Circle( 25, 25, 12.5, Color.BLUE );
        Group group = new Group(dummyCircle,square2, circle2 );

        RotateTransition rt2 = new RotateTransition( Duration.millis( 1000 ), square2 );
        rt2.setByAngle( 360 );
        rt2.setCycleCount( Animation.INDEFINITE );
        rt2.setInterpolator( Interpolator.LINEAR );
        rt2.play();

        Scene scene = new Scene(new HBox(group), 200, 200, Color.BLACK );
        primaryStage.setScene( scene );
        primaryStage.show();
    }

    public static void main( String[] args ) {
        launch( args );
    }
}

Upvotes: 2

Related Questions