以下是不需要css的解决方案,可以用于动画控件。
下面我贴出包含两个不同元素的应用程序代码。您可以运行它并查看它如何工作。
1.此区域具有动画背景
public class FilledRegion extends Region {
private final Random rand;
private ObjectProperty<Color> externalColor = new SimpleObjectProperty();
private ObjectProperty<Color> internalColor = new SimpleObjectProperty();
private Color oldExternalColor;
private Color oldInternalColor;
private Background bg;
private Timeline timeline;
private int duration;
public FilledRegion() {
rand = new Random();
this.setMinWidth(75);
oldExternalColor = getRandomColor(AnimatedGradients.baseExternalColor, AnimatedGradients.externalDelta);
oldInternalColor = getRandomColor(AnimatedGradients.baseInternalColor, AnimatedGradients.internalDelta);
externalColor.set( oldExternalColor );
internalColor.set( oldInternalColor );
setBackground();
internalColor.addListener((obs, oldColor, newColor) -> {
setBackground();
});
}
public void startAnimation() {
timeline = new Timeline();
createTimelineContent();
timeline.setOnFinished(ActionEvent -> {
createTimelineContent();
timeline.play();
});
timeline.play();
}
private void createTimelineContent() {
timeline.getKeyFrames().clear();
duration = getRandomDuration();
KeyFrame kf1 =
new KeyFrame(Duration.ZERO,
new KeyValue( externalColor, oldExternalColor ),
new KeyValue( internalColor, oldInternalColor ));
oldExternalColor = getRandomColor(AnimatedGradients.baseExternalColor, AnimatedGradients.externalDelta);
oldInternalColor = getRandomColor(AnimatedGradients.baseInternalColor, AnimatedGradients.internalDelta);
KeyFrame kf2 =
new KeyFrame(new Duration(duration),
new KeyValue( externalColor, oldExternalColor ),
new KeyValue( internalColor, oldInternalColor ));
timeline.getKeyFrames().addAll( kf1, kf2 );
}
private void setBackground() {
bg = new Background(
new BackgroundFill(
new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE,
new Stop[] { new Stop(0, externalColor.get()), new Stop(0.5, internalColor.get()), new Stop(1, externalColor.get())}
),
new CornerRadii(0),
new Insets(0, 0, 0, 0)
)
);
this.setBackground(bg);
}
private Color getRandomColor(Color color, double delta) {
int index = (int)( (color.getRed()+getRandomCoefficient(delta))*255 );
int r = ( index > 255 ) ? 255 : ( (index < 0) ? 0 : index );
index = (int)( (color.getGreen()+getRandomCoefficient(delta))*255 );
int g = ( index > 255 ) ? 255 : ( (index < 0) ? 0 : index );
index = (int)( (color.getBlue()+getRandomCoefficient(delta))*255 );
int b = ( index > 255 ) ? 255 : ( (index < 0) ? 0 : index );
return Color.rgb(r, g, b);
}
private double getRandomCoefficient(double delta) {
return ( rand.nextDouble()*2 - 1 ) * delta;
}
private int getRandomDuration() {
return (int)(( rand.nextDouble()*2 - 1 ) * AnimatedGradients.durationDelta * AnimatedGradients.baseDuration) + AnimatedGradients.baseDuration;
}}
2. 这是一个动画图标的示例
public class AnimatedIcon extends WritableImage {
private ObjectProperty<Color> topColor = new SimpleObjectProperty();
private ObjectProperty<Color> bottomColor = new SimpleObjectProperty();
private Color oldTopColor;
private Color oldBottomColor;
private Timeline timeline;
private static final int DURATION = 5000;
private static final Random rand = new Random();
private static final int ICON_WIDTH = 32;
private static final int ICON_HEIGHT = 32;
private Stage primaryStage;
public AnimatedIcon(Stage primaryStage) {
super(ICON_WIDTH, ICON_HEIGHT);
this.primaryStage = primaryStage;
oldTopColor = Color.rgb(0, 45, 0);
oldBottomColor = Color.rgb(12, 128, 12);
topColor.set(oldTopColor);
bottomColor.set(oldBottomColor);
createGraphics();
bottomColor.addListener((obs, oldColor, newColor) -> {
createGraphics();
});
}
private void createGraphics() {
PixelWriter pixelWriter = this.getPixelWriter();
for (int y = 0; y < ICON_HEIGHT; y++) {
for (int x = 0; x < ICON_WIDTH; x++) {
double position = (double)x/(double)ICON_WIDTH;
int r = (int)( ( topColor.get().getRed() - (topColor.get().getRed() - bottomColor.get().getRed())*position ) * 255 );
int g = (int)( ( topColor.get().getGreen() - (topColor.get().getGreen() - bottomColor.get().getGreen())*position ) * 255 );
int b = (int)( ( topColor.get().getBlue() - (topColor.get().getBlue() - bottomColor.get().getBlue())*position ) * 255 );
double o = topColor.get().getOpacity() - (topColor.get().getOpacity() - bottomColor.get().getOpacity())*position;
pixelWriter.setColor(x,y,Color.rgb(r,g,b,o));
}
}
int index = primaryStage.getIcons().indexOf(this);
if (index == 0) {
primaryStage.getIcons().set(index, this);
} else {
primaryStage.getIcons().add(this);
}
}
public void startAnimation() {
timeline = new Timeline();
createTimelineContent();
timeline.setOnFinished(ActionEvent -> {
createTimelineContent();
timeline.play();
});
timeline.play();
}
private void createTimelineContent() {
timeline.getKeyFrames().clear();
KeyFrame kf1 =
new KeyFrame(Duration.ZERO,
new KeyValue( topColor, oldTopColor ),
new KeyValue( bottomColor, oldBottomColor ));
oldTopColor = Color.rgb(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256), rand.nextDouble());
oldBottomColor = Color.rgb(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256), 1);
KeyFrame kf2 =
new KeyFrame(new Duration(DURATION),
new KeyValue( topColor, oldTopColor ),
new KeyValue( bottomColor, oldBottomColor ));
timeline.getKeyFrames().addAll( kf1, kf2 );
}}
这是位于上方的元素的主类
public class AnimatedGradients extends Application {
protected static int baseDuration = 10000;
protected static Color baseExternalColor = Color.rgb(0, 0, 0);
protected static Color baseInternalColor = Color.rgb(127, 127, 127);
protected static double durationDelta = 0.25;
protected static double externalDelta = 0.1;
protected static double internalDelta = 1;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
HBox root = new HBox();
root.setSpacing(1);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 761, 500, Color.BLACK);
primaryStage.setScene(scene);
AnimatedIcon ai = new AnimatedIcon(primaryStage);
primaryStage.getIcons().add(ai);
ai.startAnimation();
primaryStage.setTitle("Animated Gradients");
for (int i = 0; i < 10; i++) {
FilledRegion gr = new FilledRegion();
root.getChildren().add(gr);
gr.startAnimation();
}
primaryStage.show();
}}