I'm attempting to create something like a minimap with JavaFX, i.e. a (darkened) background image with some circles layered on top of it. Some of these circles need to be able to shed light on the background, revealing a small part of it. The following figure shows what I am aiming at.
I have worked my way forward using this SO solution, but at the moment, I am stuck because it seems that you can only set one instance of javafx.scene.effect.Lighting on the underlying StackPane.
I would really like to keep this as simple as possible and ideally only employ JavaFX. Any help is greatly appreciated :)
I recommend adding together Circles filled with a RadialGradient on a Pane with black background using BlendMode.LIGHTEN and combining this with a ImageView containing the "map" using BlendMode.MULTIPLY:
private Circle circle;
// gradient with yellow in the center and black on the border
private final static RadialGradient GRADIENT = new RadialGradient(0, 0, 0.5, 0.5, 0.5, true, CycleMethod.NO_CYCLE, new Stop(0, Color.YELLOW), new Stop(1, Color.BLACK));
private void newCircle(Pane container) {
circle = new Circle(50, GRADIENT);
circle.setBlendMode(BlendMode.LIGHTEN);
circle.setManaged(false);
container.getChildren().add(circle);
}
private void setCirclePosition(MouseEvent event) {
circle.setCenterX(event.getX());
circle.setCenterY(event.getY());
}
#Override
public void start(Stage primaryStage) {
Image image = new Image(imageURL);
ImageView imageView = new ImageView(image);
Pane mask = new Pane();
mask.setBlendMode(BlendMode.MULTIPLY);
mask.setStyle("-fx-background-color: black;");
mask.setOnMouseMoved(this::setCirclePosition); // move cricle with mouse
newCircle(mask);
// create new circle on mouse click
mask.setOnMouseClicked(evt -> {
newCircle(mask);
setCirclePosition(evt);
});
StackPane root = new StackPane(imageView, mask);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
Related
I have used Animation() method to make my view with the animation of scaling and Rotation. With the Rotation based on the Y axis, the default height and width of my view has been changed. It looks like the parallelogram.
rotation of rectangle along y-axis transformed to a parallelogram.
myview.Animate().RotationY(rotationangle)
.X(xposition)
.SetDuration(mduration)
.WithLayer()
.SetInterpolator(interpolate).Start();
My requirement:
I just want the rotation of my view no need to change its projection. How to restrict the rotation of rectangle along y-axis transformed to a parallelogram.
For more reference, please check the attached sample
now view be like,
Image
Please share your idea.
Thanks in Advance.
Note: while using PivotX and PivotY, there is no parallelogram shape. But I don't know the exact usage of that.
Regards,
Hemalatha Marikumar
is that not what are you looking for ?
it may work if you put this code in your current activity
Android: Temporarily disable orientation changes in an Activity
Do you want to create a 2D rotation?
You could try to use ScaleAnimation to rotate the view. If you want to rotate 360 degrees, you could use AnimationListener.
For example:
Button myview = (Button)FindViewById(Resource.Id.button2);
ScaleAnimation scaleAnimation = new ScaleAnimation(1, 0, 1, 1,
Android.Views.Animations.Dimension.RelativeToParent, 0.5f, Android.Views.Animations.Dimension.RelativeToParent, 0.5f);
ScaleAnimation scaleAnimation2 = new ScaleAnimation(0, 1, 1, 1,
Android.Views.Animations.Dimension.RelativeToParent, 0.5f, Android.Views.Animations.Dimension.RelativeToParent, 0.5f);
scaleAnimation.Duration = 4000;
scaleAnimation.SetAnimationListener(new AnimationListener(myview, scaleAnimation2));
scaleAnimation2.Duration = 4000;
myview.StartAnimation(scaleAnimation);
The Listener:
public class AnimationListener :Java.Lang.Object, IAnimationListener
{
View view;
Animation animation2;
public AnimationListener(View view, Animation animation)
{
this.view = view;
this.animation2 = animation;
}
public void OnAnimationEnd(Animation animation)
{
view.StartAnimation(animation2);
}
public void OnAnimationRepeat(Animation animation)
{
}
public void OnAnimationStart(Animation animation)
{
}
}
I want to draw an ellipse and a rounded rectangle in GEF editor.
I am not using Canvas and am using XY layout.I am able to draw rectangle in this layout but not the other two.
Please guide
To draw a rounded rectangle you need to extend Figure and inside this figure draw a rectangle with rounded borders
(Disclaimer - This is a reduced version of the code I use for a rounded rectangle here. Pretty sure it will work but I didn't test it)
public class RoundedRectangle extends Figure {
private final RoundedRectangle rectangle;
public RoundedRectangle() {
super();
setLayoutManager(new XYLayout());
rectangle = new RoundedRectangle();
rectangle.setCornerDimensions(new Dimension(20, 20)); // This is where the rounding happens
// Anything else you want to customize
add(rectangle);
}
#Override
protected void paintFigure(Graphics graphics) {
Rectangle r = getBounds().getCopy();
setConstraint(rectangle, new Rectangle(0, 0, r.width, r.height));
}
}
I have a issue with my Marquee animation with JavaFX. I have a HBox with three Nodes and in the second node I have a Text node inside that I need do the Marquee transformation, but when the text goes out of the second node I need it doesn't be visible.
I'll go to set a picture to show my issue (the text is visible in the white area).
My Hbox code:
HBox bill = new HBox(0);
bill.getChildren().addAll(logoPane,product,total);
bill.setBackground(new Background(new BackgroundFill(Color.web("#FFFFFF"), CornerRadii.EMPTY, Insets.EMPTY)));
bill.setHgrow(product, Priority.ALWAYS);
Animation:
timelineAnimation = new Timeline();
final KeyValue kv = new KeyValue(productLabel.translateXProperty(), -1000);
final KeyFrame kf = new KeyFrame(Duration.millis(2000), kv);
timelineAnimation.getKeyFrames().add(kf);
And how I define my product node:
productLabel.setFont(new Font("Times New Roman",30));
product = new StackPane();
product.setMaxWidth(2000);
product.setMaxHeight(100);
product.setMinWidth(574);
product.setMinHeight(100);
product.getChildren().add(productLabel);
product.setBackground(new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
product.setAlignment(productLabel, Pos.CENTER);
Hope it was enough information.
Thanks!
Simply add a Rectangle as clip for the product pane and bind it's size to the size of the pane:
Rectangle clip = new Rectangle();
product.layoutBoundsProperty().addListener((observable, oldValue, newValue) -> {
clip.setWidth(newValue.getWidth());
clip.setHeight(newValue.getHeight());
});
product.setClip(clip);
This will make sure no descendants of product are drawn outside the bounds of this node.
I am trying to create a continuous animation, eventually the goal would be a bouncing ball that bounces off the edges of the screen, however, one step at a time.
I started with the sample code from Oracle that has an animation of circles that move for 40 seconds.
public void start(Stage primaryStage)
{
Group root = new Group();
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
Group circles = new Group();
for (int i = 0; i < 1; i++)
{
MovingCircle circle = new MovingCircle(150, Color.web("white", 0.05));
circle.setStrokeType(StrokeType.OUTSIDE);
circle.setStroke(Color.web("black", 0.16));
circle.setStrokeWidth(4);
circles.getChildren().add(circle);
}
root.getChildren().add(circles);
Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
for (Node circle: circles.getChildren())
{
if(circle instanceof MovingCircle)
{
MovingCircle c = (MovingCircle)circle;
timeline.getKeyFrames().addAll(
/* new KeyFrame(Duration.ZERO, // set start position at 0
new KeyValue(circle.translateXProperty(), random() * 800),
new KeyValue(circle.translateYProperty(), random() * 600)
),*/
new KeyFrame(new Duration(10), // set end position at 40s
c.getXMovement(), c.getYMovement())
);
c.updateCenter();
}
}
// play 40s of animation
timeline.play();
primaryStage.show();
}
I created a new MovingCircle that extends Circle to try and add other stuff to it later. The two new class methods return exactly what was commented out from the default code given.
I changed the cycle to indefinite so that it would go forever. All the circle does though is bounce between its original starting point and the translated point. I have tried updating its center location in hopes that the next bounce would move it to a different location, however, that doesn't work.
I am at quite a loss as to what to try next to get this working more the way I was hoping.
Hey I am trying to make a simple 2d scroller but I simply cannot seem to get the picture to scroll. I am using an ImagveView for the picture, and I have tried both a translatetransition and a pathtransition, but I can't get any good results? Here is my code:
public void aboutSceneAnimation() {
Rectangle2D psb = Screen.getPrimary().getVisualBounds();
Path path = new Path();
MoveTo moveTo = new MoveTo();
moveTo.setX(0.0);
path.getElements().add(moveTo);
PathTransition pt = new PathTransition();
pt.setDuration(Duration.INDEFINITE);
pt.setNode(map);
pt.setPath(path);
pt.setCycleCount(4);
pt.setAutoReverse(true);
pt.play();
}
public Scene aboutScene() {
Rectangle2D psb = Screen.getPrimary().getVisualBounds();
//Create the map
BorderPane border = new BorderPane();
border.getChildren().addAll(map2);
//Size the map
map2.setFitWidth(psb.getWidth());
map2.setFitHeight(psb.getHeight());
Scene scene = new Scene(border, 500, 500);
aboutSceneAnimation();
return scene;
}
The way it works is that when the program starts there is a start scene loaded into my stage, and then I just show the stage. When a button is pressed I simply change to the aboutScene which also calls the aboutSceneAnimation, which is where I want the map to scroll. Any ideas would be greatly appreciated!
-Cheers
You need to use a Pane instead of a BorderPane, because in a BorderPane the center node will be resized to fill the available space in the middle.
In your PathTransition you only add from where to start, i. e. the MoveTo, but you don't add where it should go, e. g. a LineTo.
Additional note:
Since your example in the question contains only bits and pieces that don't work together, please read about How to create a Minimal, Complete, and Verifiable example.