你可以:
或
2D场景中的路径动画
该2D示例演示了在时间轴中同时使用路径变换和旋转技术.
import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SolApp extends Application {
private static final double S = 400, C = S / 2, O = S * 3/8;
private static final Duration T = Duration.seconds(10);
private static final Color INDIA_INK = Color.web("#3c3f4a");
@Override
public void start(Stage stage) {
Circle sun = new Circle(
C, C,
S/10,
Color.或ANGERED
);
Circle earth = new Circle(
C + O, C,
S/40,
Color.PALETURQUOISE
);
Circle orbit = new Circle(C, C, O);
orbit.setFill(null);
orbit.setStroke(Color.GREEN);
orbit.setStrokeWidth(2);
Pane space = new Pane(sun, orbit, earth);
space.setPrefSize(S, S);
space.setBackground(Background.fill(INDIA_INK));
// Animation orbiter = getTimelineOrbiter(earth);
Animation orbiter = getPathTransitionOrbiter(orbit, earth);
stage.setScene(new Scene(space));
stage.show();
orbiter.play();
}
private static Transition getPathTransitionOrbiter(Circle orbit, Circle earth) {
PathTransition orbiter = new PathTransition(T, orbit, earth);
orbiter.setInterpolator(Interpolator.LINEAR);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
private static Timeline getTimelineOrbiter(Circle earth) {
Rotate rotate = new Rotate();
rotate.setPivotX(C);
rotate.setPivotY(C);
earth.getTransforms().add(rotate);
Timeline orbiter = new Timeline(
new KeyFrame(
Duration.ZERO,
new KeyValue(
rotate.angleProperty(),
0
)
),
new KeyFrame(
T,
new KeyValue(
rotate.angleProperty(),
360
)
)
);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
public static void main(String[] args) {
launch(args);
}
}
在路径上定位 node
如果要调整环游的起点,可以在播放轨道器动画之前应用以下行,根据需要调整0到1之间的除数.
orbiter.jumpTo(T.divide(.17));
这将允许您沿任意路径将 node 放置在任何位置(即使您没有沿路径设置动画).
确定 node 的方向
对于圆和球体(如此处示例中的圆和球体),您不会注意到 node 方向,但对于非对称 node ,您可能希望将 node 设置为orient,以使其在放置在路径上或沿路径移动时指向所需的方向.
3D场景中的路径动画
同样的技术也适用于3D场景中的动画对象.
import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SolAppThreeD extends Application {
private static final double S = 400, C = S / 2, O = S * 3/8;
private static final Duration T = Duration.seconds(10);
private static final Color INDIA_INK = Color.web("#3c3f4a");
@Override
public void start(Stage stage) {
Sphere sun = new Sphere(
S/10
);
sun.setMaterial(new PhongMaterial(Color.或ANGERED));
sun.setTranslateX(C);
sun.setTranslateY(C);
PointLight sunsRadiance = new PointLight(Color.LIGHTYELLOW);
sunsRadiance.translateXProperty().bind(sun.translateXProperty());
sunsRadiance.translateYProperty().bind(sun.translateYProperty());
sunsRadiance.translateZProperty().bind(sun.translateZProperty());
Sphere earth = new Sphere(
S/40
);
earth.setMaterial(new PhongMaterial(Color.DARKTURQUOISE));
earth.setTranslateX(C + O);
earth.setTranslateY(C);
// an f(xyz) Torus could be used instead here for higher fidelity.
// https://github.com/FXyz/FXyzLib/blob/master/src/org/fxyz/shapes/Torus.java
Circle orbit = new Circle(C, C, O);
orbit.setFill(null);
orbit.setStroke(Color.GREEN.deriveColor(0, 1, 1, .8));
orbit.setStrokeWidth(4);
Animation orbiter = getPathTransitionOrbiter(orbit, earth);
Group space = new Group(sun, sunsRadiance, orbit, earth);
PerspectiveCamera camera = new PerspectiveCamera();
DirectionalLight cameraLight = new DirectionalLight(Color.GRAY);
cameraLight.translateXProperty().bind(camera.translateXProperty());
cameraLight.translateYProperty().bind(camera.translateYProperty());
cameraLight.translateZProperty().bind(camera.translateZProperty());
Rotate xform = new Rotate(-80, new Point3D(1, 0, 0));
xform.setPivotX(C);
xform.setPivotY(C);
space.getTransforms().add(xform);
Group root = new Group(cameraLight, space);
Scene scene = new Scene(root, S, S, true, SceneAntialiasing.BALANCED);
scene.setCamera(camera);
scene.setFill(INDIA_INK);
stage.setScene(scene);
stage.show();
orbiter.play();
}
private static Transition getPathTransitionOrbiter(Circle orbit, Node satellite) {
PathTransition orbiter = new PathTransition(T, orbit, satellite);
orbiter.setInterpolator(Interpolator.LINEAR);
orbiter.setCycleCount(Animation.INDEFINITE);
return orbiter;
}
public static void main(String[] args) {
launch(args);
}
}
第三种(更复杂的)技术(此处未显示)将设置为use an AnimationTimer,每次调用计时器中的handle
方法以更新场景时,计算和调整 node 的平移属性.此技术通常用于游戏循环或物理模型中,其中使用速度向量对对象进行建模,速度向量根据重力、碰撞和反弹等物理属性更新其位置.