一、效果图
二、 代码部分
1.SpringFestival类:
1.创建时间轴,将SpringFestivalAnimation类(下面)的动画作为关键帧插入
// 创建时间轴
Timeline timeline = new Timeline();
timeline.setAutoReverse(true);
2.时间轴随着time值的累加而运行
// 插入关键帧动画
KeyFrame rotate_left = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.rotate(1, 0);
}
});
time += 1;
KeyFrame rotate_center = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_center.rotate(1, 0);
}
});
time += 1;
KeyFrame rotate_right = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_right.rotate(9, 5);
}
});
time += 9;
KeyFrame move_slow = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
// 设置新背景图片
ImagePattern imagePattern = new ImagePattern(new Image("/image/snow.png"), 0, 0, 1, 1, true);
pane.setBackground(new Background(new BackgroundFill(imagePattern, CornerRadii.EMPTY, Insets.EMPTY)));
animation_left.move_slow();
animation_center.move_slow();
animation_right.move_slow();
}
});
time += 2;
KeyFrame move_fast = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.move_fast();
animation_center.move_fast();
animation_right.move_fast();
}
});
time += 2;
KeyFrame move_slow_again = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.move_slow();
animation_center.move_slow();
animation_right.move_slow();
}
});
time += 1.5;
KeyFrame move_fast_again = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.move_fast();
animation_center.move_fast();
animation_right.move_fast();
}
});
time += 2;
KeyFrame move_nomal = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.move_nomal();
animation_center.move_nomal();
animation_right.move_nomal();
}
});
time += 3.2;
KeyFrame duiLian_left = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_left.duiLian(new ImageView("/image/duilian_left.jpg"));
}
});
time += 1;
KeyFrame duiLian_head = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_top.duiLian(new ImageView("/image/duilian_head.jpg"));
}
});
time += 1;
KeyFrame duiLian_right = new KeyFrame(Duration.millis(time * second), new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
animation_right.duiLian(new ImageView("/image/duilian_right.jpg"));
}
});
time += 1;
3.将若干关键帧加入到timeline时间轴中
timeline.getKeyFrames().addAll(
rotate_left,
rotate_center,
rotate_right,
move_slow,
move_fast,
move_slow_again,
move_fast_again,
move_nomal,
duiLian_left,
duiLian_head,
duiLian_right
);
timeline.play();
2.SpringFestivalAnimation类
1.“福”的旋转(RotateTransition),放大(ScaleTransition)
public void rotate(double time, double speed) {
view = new ImageView("/image/Fu.png");
view.setFitHeight(100);
view.setFitWidth(100);
getChildren().addAll(view);
// 旋转
RotateTransition rotateTransition = new RotateTransition(Duration.millis(1000 * time), view);
rotateTransition.setByAngle(360 * ((360 + 45) / 360.0 + speed));
rotateTransition.setCycleCount(1);
// 放大
ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(6000), view);
scaleTransition.setToX(20f);
scaleTransition.setToY(20f);
scaleTransition.setCycleCount(1);
ParallelTransition parallelTransition = new ParallelTransition();
if (time == 9) {
parallelTransition.getChildren().addAll(
scaleTransition,
rotateTransition
);
} else {
parallelTransition.getChildren().addAll(
rotateTransition
);
}
parallelTransition.play();
}
2.“灯笼”按路径(Path)鬼畜走位,正常移动(TranslateTransition)
public void move_slow() {
view = new ImageView("/image/lantern.png");
view.setFitHeight(200);
view.setFitWidth(200);
// 先把之前的结点删除再添加新结点
getChildren().clear();
getChildren().addAll(view);
// 创建路径
path = new Path();
path.getElements().add(new MoveTo(0, 100));
path.getElements().add(new CubicCurveTo(100, 50, 200, 100, 200, 100));
path.getElements().add(new CubicCurveTo(200, 100, 300, 50, 400, 100));
path.getElements().add(new CubicCurveTo(400, 100, 500, 50, 600, 100));
path.getElements().add(new CubicCurveTo(600, 100, 700, 50, 800, 100));
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(1500));
pt.setPath(path);
pt.setNode(view);
pt.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(1);
pt.setAutoReverse(false);
pt.play();
}
public void move_fast() {
view = new ImageView("/image/lantern.png");
view.setFitHeight(200);
view.setFitWidth(200);
// 先把之前的结点删除再添加新结点
getChildren().clear();
getChildren().addAll(view);
path = new Path();
path.getElements().add(new MoveTo(1000, 300));
path.getElements().add(new LineTo(800, 0));
path.getElements().add(new LineTo(600, 300));
path.getElements().add(new LineTo(400, 0));
path.getElements().add(new LineTo(200, 300));
path.getElements().add(new LineTo(0, 0));
path.getElements().add(new LineTo(-200, 300));
path.getElements().add(new LineTo(-400, 0));
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(2000));
pt.setPath(path);
pt.setNode(view);
pt.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(1);
pt.setAutoReverse(false);
pt.play();
}
public void move_nomal() {
view = new ImageView("/image/lantern.png");
view.setFitHeight(200);
view.setFitWidth(200);
// 先把之前的结点删除再添加新结点
getChildren().clear();
getChildren().addAll(view);
// 移动
TranslateTransition translateTransition = new TranslateTransition(Duration.millis(700), view);
translateTransition.setFromX(0);
translateTransition.setToX(1000);
translateTransition.setCycleCount(4);
translateTransition.setAutoReverse(true);
ParallelTransition parallelTransition = new ParallelTransition();
parallelTransition.getChildren().addAll(
translateTransition
);
parallelTransition.play();
}
3.“对联”的淡入淡出(FadeTransition)
public void duiLian(ImageView view) {
// 根据图片的实际高度设置图片的大小
if (view.getImage().getHeight() < 500) {
view.setFitHeight(70);
view.setFitWidth(200);
} else {
view.setFitHeight(350);
view.setFitWidth(70);
}
// 先把之前的结点删除再添加新结点
getChildren().clear();
getChildren().addAll(view);
// 淡入
FadeTransition fadeTransition = new FadeTransition(Duration.millis(1000), view);
fadeTransition.setFromValue(1.0f);
fadeTransition.setToValue(0.3f);
fadeTransition.setCycleCount(2);
fadeTransition.setAutoReverse(true);
// 放大
ScaleTransition scaleTransition = new ScaleTransition(Duration.millis(1000), view);
scaleTransition.setToX(2f);
scaleTransition.setToY(2f);
scaleTransition.setCycleCount(2);
scaleTransition.setAutoReverse(true);
ParallelTransition parallelTransition = new ParallelTransition();
parallelTransition.getChildren().addAll(
fadeTransition,
scaleTransition
);
parallelTransition.play();
}
三、总结
1.图片音乐等资源可以在github上直接获取(为了摆烂,特意找了有水印的)OracleRay/SpringFestival: 欢度春节 (github.com)https://github.com/OracleRay/SpringFestival2.代码还存在诸多bug(反正也是摆烂,正经人谁用JavaFX做动画......),没事儿的hxd可以试着粘过去改改bug哈哈哈