前面的3D暂时先翻译到那,还有一点3D的内容后面有时间在弄,由于迫切的想了解动画效果,所以先来看动画了,这其实并不影响学习。现在来讲讲javaFX中的动画效果。
Animation Basics(动画基础)
在javaFX中动画被分为时间轴动画和过渡动画。Timeline和Transition是javafx.animation.Animation
类的子类。下面分别介绍这两个类,关于该类更多的信息,请参考API。
Transitions(过渡/转变)
Transitions可以创建多个动画顺序执行或者并列执行。Fade Transition(淡入淡出)
该效果在给定时间内改变节点的不透明度效果来实现。下面的这段代码将演示一个圆角矩形的淡入淡出效果,首先创建一个圆角矩形,然后给他应用淡入淡出效果。
<span style="font-size:14px;">
final Rectangle rect1 = new Rectangle(10, 10, 100, 100);
rect1.setArcHeight(20);
rect1.setArcWidth(20);
rect1.setFill(Color.RED);
...
FadeTransition ft = new FadeTransition(Duration.millis(3000), rect1);
ft.setFromValue(1.0);
ft.setToValue(0.1);
ft.setCycleCount(Timeline.INDEFINITE);
ft.setAutoReverse(true);
ft.play();
</span>
Path Transition(路径转变)
path transition的作用是在给定时间内使一个节点元素沿着一条路径移动到另一处的效果。下图是一个演示截图。
下面的代码片段展示了一个圆角矩形在path transition中的应用。在代码中,首先一个圆角矩形被创建,然后创建一个路径动画应用于矩形。
<span style="font-size:14px;">
</span><span style="font-size:14px;">@Override
public void start(Stage arg0) throws Exception {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
//创建一个矩形
final Rectangle rect=new Rectangle(0, 0, 40, 40);
rect.setArcHeight(10);
rect.setArcWidth(10);
rect.setFill(Color.RED);
//将矩形作为一个Node方到Parent中
root.getChildren().add(rect);
//创建路径
javafx.scene.shape.Path path=new javafx.scene.shape.Path();
path.getElements().add(new MoveTo(20, 20));
path.getElements().add(new CubicCurveTo(380, 0, 380, 120, 200, 120));
path.getElements().add(new CubicCurveTo(0, 120, 0, 240, 380, 240));
//创建路径转变
PathTransition pt=new PathTransition();
pt.setDuration(Duration.millis(4000));//设置持续时间4秒
pt.setPath(path);//设置路径
pt.setNode(rect);//设置物体
pt.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
//设置周期性,无线循环
pt.setCycleCount(Timeline.INDEFINITE);
pt.setAutoReverse(true);//自动往复
pt.play();//启动动画
arg0.setScene(scene);
arg0.show();
}
</span>
Parallel Transition(并行演化过渡效果)
该类用来同时执行一组动画效果。下面的代码展示了一个圆角矩形的淡入淡出,平移,旋转,缩放效果。你可以直接将代码copy至你的eclipse中
<span style="font-size:14px;">
@Override
public void start(Stage arg0) throws Exception {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
Rectangle rectParallel = new Rectangle(10,200,50, 50);
rectParallel.setArcHeight(15);
rectParallel.setArcWidth(15);
rectParallel.setFill(Color.DARKBLUE);
rectParallel.setTranslateX(50);
rectParallel.setTranslateY(75);
root.getChildren().add(rectParallel);
//定义矩形的淡入淡出效果
FadeTransition fadeTransition=new FadeTransition(Duration.millis(3000), rectParallel);
fadeTransition.setFromValue(1.0f);
fadeTransition.setToValue(0.3f);
fadeTransition.setCycleCount(2);
fadeTransition.setAutoReverse(true);
//fadeTransition.play();
//定义矩形的平移效果
TranslateTransition translateTransition=new TranslateTransition(Duration.millis(2000), rectParallel);
translateTransition.setFromX(50);
translateTransition.setToX(350);
translateTransition.setCycleCount(2);
translateTransition.setAutoReverse(true);
//translateTransition.play();
//定义矩形旋转效果
RotateTransition rotateTransition =
new RotateTransition(Duration.millis(3000), rectParallel);
rotateTransition.setByAngle(180f);//旋转度数
rotateTransition.setCycleCount(4);
rotateTransition.setAutoReverse(true);
//rotateTransition.play();
//矩形的缩放效果
ScaleTransition scaleTransition =
new ScaleTransition(Duration.millis(2000), rectParallel);
scaleTransition.setToX(2f);
scaleTransition.setToY(2f);
scaleTransition.setCycleCount(2);
scaleTransition.setAutoReverse(true);
//scaleTransition.play();
//并行执行动画
ParallelTransition parallelTransition=new ParallelTransition(fadeTransition,rotateTransition,
translateTransition,scaleTransition);
parallelTransition.setCycleCount(Timeline.INDEFINITE);
parallelTransition.play();
arg0.setScene(scene);
arg0.show();
}
</span>
Sequential Transition(顺序执行动画效果)
该类用来一个接着一个的执行定义好的动画。我们只需要将上面的代码的并行执行动画的部分改成如下代码即可可测效果:
SequentialTransition sequentialTransition=new SequentialTransition(fadeTransition,rotateTransition,
translateTransition,scaleTransition);
sequentialTransition.setCycleCount(Timeline.INDEFINITE);
sequentialTransition.play();
值得注意的是,执行的先后顺序却决于你的动画放置的先后顺序。
Timeline Animation(时间轴动画)
动画被分为相关的属性,例如尺寸、位置、颜色等。时间轴提供了更新属性值沿着时间的进展 的功能。JavaFX支持关键帧动画。在关键帧动画里,动画在图形场景中的转换状态由开始和结束的快照(关键帧)来描述特定时间的画面状态。系统可以自动执行动画。它可以停止、暂停、恢复、反向或重复运动要求。
Basic Timeline Animation(基本的时间轴动画)
下面的代码展示了一个矩形在500ms内水平移动,位置从x=100 移动到x=300.
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane border=new BorderPane();
Scene scene=new Scene(border, 500, 500);
//创建矩形,起点在x=100,y=50的位置
final Rectangle rect=new Rectangle(100, 50, 100, 50);
rect.setFill(Color.RED);
border.getChildren().add(rect);
//创建时间轴
final Timeline timeline=new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);//设置周期运行循环往复
timeline.setAutoReverse(true);//设置动画的自动往返效果
//将x的位置在500ms内移动到300处
final KeyValue kv=new KeyValue(rect.xProperty(), 300);
final KeyFrame kf=new KeyFrame(Duration.millis(500), kv);
//将关键帧加到时间轴中
timeline.getKeyFrames().add(kf);
timeline.play();//运行
primaryStage.setScene(scene);
primaryStage.show();
}
Timeline Events(时间轴事件)
javaFX提供了一系列的事件用来在时间轴运行的期间触发。下面的代码将演示在指定的范围内改变圆的半径,使用关键帧在场景中随机触发圆的x坐标。
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.Lighting;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.util.Duration;
public class TimelineEvents extends Application {
//main timeline
private Timeline timeline;
private AnimationTimer timer;
//variable for storing actual frame
private Integer i=0;
@Override public void start(Stage stage) {
Group p = new Group();
Scene scene = new Scene(p);
stage.setScene(scene);
stage.setWidth(500);
stage.setHeight(500);
p.setTranslateX(80);
p.setTranslateY(80);
//create a circle with effect
final Circle circle = new Circle(20, Color.rgb(156,216,255));
circle.setEffect(new Lighting());
//create a text inside a circle
final Text text = new Text (i.toString());
text.setStroke(Color.BLACK);
//create a layout for circle with text inside
final StackPane stack = new StackPane();
stack.getChildren().addAll(circle, text);
stack.setLayoutX(30);
stack.setLayoutY(30);
p.getChildren().add(stack);
stage.show();
//create a timeline for moving the circle
timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
//You can add a specific action when each frame is started.
timer = new AnimationTimer() {
@Override
public void handle(long l) {
text.setText(i.toString());
i++;
}
};
//create a keyValue with factory: scaling the circle 2times
KeyValue keyValueX = new KeyValue(stack.scaleXProperty(), 2);
KeyValue keyValueY = new KeyValue(stack.scaleYProperty(), 2);
//create a keyFrame, the keyValue is reached at time 2s
Duration duration = Duration.millis(2000);
//one can add a specific action when the keyframe is reached
EventHandler onFinished = new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
stack.setTranslateX(java.lang.Math.random()*200-100);
//reset counter
i = 0;
}
};
KeyFrame keyFrame = new KeyFrame(duration, onFinished , keyValueX, keyValueY);
//add the keyframe to the timeline
timeline.getKeyFrames().add(keyFrame);
timeline.play();
timer.start();
}
public static void main(String[] args) {
Application.launch(args);
}
}