JavaFX官方教程(十一)之动画基础

翻译自   动画基础

动画基础提供基本动画概念,包含以下部分:

 

JavaFX中的动画可以分为时间轴动画和过渡。本章提供了每种动画类型的示例。

Timeline并且Transitionjavafx.animation.Animation该类的子类。有关特定类,方法或其他功能的更多信息,请参阅API文档。

转变

JavaFX中的转换提供了在内部时间轴中合并动画的方法。可以组合转换以创建并行或顺序执行的多个动画。有关详细信息,请参见并行转换顺序转换部分。以下部分提供了一些过渡动画示例。

淡出过渡

淡入淡出过渡会在给定时间内更改节点的不透明度。

示例3-1显示了应用于矩形的淡入淡出过渡的代码片段。首先创建一个带圆角的矩形,然后对其应用淡入淡出过渡。

例3-1淡入淡出过渡

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();

路径转换

路径转换在给定时间内沿着路径将节点从一端移动到另一端。

图3-1路径转换

示例3-2显示了应用于矩形的路径转换的代码段。当矩形到达路径的末尾时,动画将反转。在代码中,首先创建一个带圆角的矩形,然后创建一个新的路径动画并应用于该矩形。

例3-2路径转换

final Rectangle rectPath = new Rectangle (0, 0, 40, 40);
rectPath.setArcHeight(10);
rectPath.setArcWidth(10);
rectPath.setFill(Color.ORANGE);
...
Path path = new 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 pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(4000));
pathTransition.setPath(path);
pathTransition.setNode(rectPath);
pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathTransition.setCycleCount(Timeline.INDEFINITE);
pathTransition.setAutoReverse(true);
pathTransition.play();

并行过渡

并行转换同时执行多个转换。

示例3-3显示了用于执行应用于矩形的淡入淡出,平移,旋转和缩放过渡的并行过渡的代码片段。

图3-2并行转换


例3-3并行转换

Rectangle rectParallel = new Rectangle(10,200,50, 50);
rectParallel.setArcHeight(15);
rectParallel.setArcWidth(15);
rectParallel.setFill(Color.DARKBLUE);
rectParallel.setTranslateX(50);
rectParallel.setTranslateY(75);
...
        FadeTransition fadeTransition = 
            new FadeTransition(Duration.millis(3000), rectParallel);
        fadeTransition.setFromValue(1.0f);
        fadeTransition.setToValue(0.3f);
        fadeTransition.setCycleCount(2);
        fadeTransition.setAutoReverse(true);
        TranslateTransition translateTransition =
            new TranslateTransition(Duration.millis(2000), rectParallel);
        translateTransition.setFromX(50);
        translateTransition.setToX(350);
        translateTransition.setCycleCount(2);
        translateTransition.setAutoReverse(true);
        RotateTransition rotateTransition = 
            new RotateTransition(Duration.millis(3000), rectParallel);
        rotateTransition.setByAngle(180f);
        rotateTransition.setCycleCount(4);
        rotateTransition.setAutoReverse(true);
        ScaleTransition scaleTransition = 
            new ScaleTransition(Duration.millis(2000), rectParallel);
        scaleTransition.setToX(2f);
        scaleTransition.setToY(2f);
        scaleTransition.setCycleCount(2);
        scaleTransition.setAutoReverse(true);
        
        parallelTransition = new ParallelTransition();
        parallelTransition.getChildren().addAll(
                fadeTransition,
                translateTransition,
                rotateTransition,
                scaleTransition
        );
        parallelTransition.setCycleCount(Timeline.INDEFINITE);
        parallelTransition.play();

顺序转换

顺序转换一个接一个地执行几个转换。

例3-4显示了一个接一个地执行的顺序转换的代码。淡化,平移,旋转和缩放应用于矩形的过渡。

例3-4顺序转换

Rectangle rectSeq = new Rectangle(25,25,50,50);
rectSeq.setArcHeight(15);
rectSeq.setArcWidth(15);
rectSeq.setFill(Color.CRIMSON);
rectSeq.setTranslateX(50);
rectSeq.setTranslateY(50);

...

         FadeTransition fadeTransition = 
            new FadeTransition(Duration.millis(1000), rectSeq);
        fadeTransition.setFromValue(1.0f);
        fadeTransition.setToValue(0.3f);
        fadeTransition.setCycleCount(1);
        fadeTransition.setAutoReverse(true);
 
        TranslateTransition translateTransition =
            new TranslateTransition(Duration.millis(2000), rectSeq);
        translateTransition.setFromX(50);
        translateTransition.setToX(375);
        translateTransition.setCycleCount(1);
        translateTransition.setAutoReverse(true);
 
        RotateTransition rotateTransition = 
            new RotateTransition(Duration.millis(2000), rectSeq);
        rotateTransition.setByAngle(180f);
        rotateTransition.setCycleCount(4);
        rotateTransition.setAutoReverse(true);
 
        ScaleTransition scaleTransition = 
            new ScaleTransition(Duration.millis(2000), rectSeq);
        scaleTransition.setFromX(1);
        scaleTransition.setFromY(1);
        scaleTransition.setToX(2);
        scaleTransition.setToY(2);
        scaleTransition.setCycleCount(1);
        scaleTransition.setAutoReverse(true);

sequentialTransition = new SequentialTransition();
sequentialTransition.getChildren().addAll(
        fadeTransition,
        translateTransition,
        rotateTransition,
        scaleTransition);
sequentialTransition.setCycleCount(Timeline.INDEFINITE);
sequentialTransition.setAutoReverse(true);

sequentialTransition.play();

有关动画和过渡的更多信息,请参阅SDK中的API文档和Ensemble项目中的“动画”部分。

时间线动画

动画由其相关属性(例如大小,位置和颜色等)驱动。Timeline提供了沿着时间进展更新属性值的功能。JavaFX支持关键帧动画。在关键帧动画中,图形场景的动画状态转换由特定时间场景状态的开始和结束快照(关键帧)声明。系统可以自动执行动画。它可以在请求时停止,暂停,恢复,反向或重复移动。

基本时间线动画

例3-5中的代码水平设置一个矩形,并将其从原始位置移动X=100X=300500毫秒。要水平设置对象动画,请更改x坐标并保持y坐标不变。

图3-3水平移动

例3-5显示了基本时间轴动画的代码片段。

例3-5时间轴动画

final Rectangle rectBasicTimeline = new Rectangle(100, 50, 100, 50);
rectBasicTimeline.setFill(Color.RED);
...
final Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
final KeyValue kv = new KeyValue(rectBasicTimeline.xProperty(), 300);
final KeyFrame kf = new KeyFrame(Duration.millis(500), kv);
timeline.getKeyFrames().add(kf);
timeline.play();

时间线活动

JavaFX提供了合并在时间线播放期间可以触发的事件的方法。示例3-6中的代码更改指定范围内圆的半径,并KeyFrame触发场​​景的x坐标中圆的随机转换。

示例3-6时间轴事件

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);
    }
  } 

插值

插值定义了对象在运动的起点和终点之间的位置。您可以使用Interpolator类的各种内置实现,也可以实现自己的Interpolator来实现自定义插值行为。

内置插补器

JavaFX提供了几个内置插补器,您可以使用它们在动画中创建不同的效果。默认情况下,JavaFX使用线性插值来计算坐标。

例3-7显示了一个代码片段,其中EASE_BOTH插值器实例被添加到基本时间轴动画中的KeyValue。当对象到达其起点和终点时,此插补器会创建弹簧效果。

例3-7内置插补器

final Rectangle rectBasicTimeline = new Rectangle(100, 50, 100, 50);
rectBasicTimeline.setFill(Color.BROWN);
...
final Timeline timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
final KeyValue kv = new KeyValue(rectBasicTimeline.xProperty(), 300,
 Interpolator.EASE_BOTH);
final KeyFrame kf = new KeyFrame(Duration.millis(500), kv);
timeline.getKeyFrames().add(kf);
timeline.play();

定制插补器

除了内置插补器,您还可以实现自己的插补器来实现自定义插值行为。自定义插补器示例包含两个java文件。例3-8显示了一个自定义插值器,用于计算动画的y坐标。例3-9显示了使用AnimationBooleanInterpolator的动画的代码片段。

例3-8自定义插补器

public class AnimationBooleanInterpolator extends Interpolator {
    @Override
    protected double curve(double t) {
        return Math.abs(0.5-t)*2 ;
    }
}

示例3-9使用自定义插值器的动画

final KeyValue keyValue1 = new KeyValue(rect.xProperty(), 300);
 AnimationBooleanInterpolator yInterp = new AnimationBooleanInterpolator();
 final KeyValue keyValue2 = new KeyValue(rect.yProperty(), 0., yInterp);

应用文件

NetBeans项目 

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: JavaFX是一个为Java开发的图形化界面工具包,它包含了许多基本的控件、动画特效和各种布局管理器等,可以方便地实现图形化界面的开发。JavaFX官方教程提供了从基础到高级的全面指南,涵盖了JavaFX应用程序的所有方面。 JavaFX官方教程包含了许多实践性强的教程,以及一些官方的示例和练习,可以让开发者快速上手JavaFX的各种功能。通过这些教程,开发者可以了解如何创建一个好看的用户界面、如何使用各种布局管理器来处理界面的布局、如何处理用户输入、如何将多媒体内容嵌入到应用程序中、如何使用动画和过渡效果来添加更多的交互性等等。 此外,JavaFX官方教程还包含了关于使用FXML(一个XML格式的用户界面描述语言)来创建界面的详细指导。FXML允许开发者将用户界面和应用程序的逻辑分离,可以使应用程序更加易于维护和修改。 总的来说,JavaFX官方教程是一个非常有价值的指南,可以帮助开发者在JavaFX中深入学习,构建出优秀的用户界面,并为应用程序添加高级的交互功能和效果。 ### 回答2: JavaFX是Java平台上的一个用于创建富客户端应用程序的GUI框架。官方教程的中文版可以帮助Java开发人员更好地学习和掌握JavaFX框架的使用。 官方教程提供了详细的指导,帮助开发人员理解JavaFX布局、控件、特效、样式和可观察值等方面,包括如何使用FXML创建用户界面。此外,教程还介绍了JavaFX的图形和媒体处理功能,通过实例和代码示例,向开发人员展示了如何构建相应的用户界面和交互。 教程的内容翔实且易于理解,适合Java开发人员从入门到精通JavaFX。同时,教程对于使用Eclipse和IntelliJ IDEA等开发工具的Java开发人员更加友好,帮助他们快速掌握JavaFX的开发流程和相关技术。 总体来说,JavaFX官方教程中文版是一个非常有价值的学习资料,对于Java开发人员来说是一个必备的工具。它的存在可以让开发人员快速掌握JavaFX的开发技巧,将其应用于实际开发中,提高开发效率、提升开发质量。 ### 回答3: JavaFX是Java平台上的一个用户界面框架,用它可以开发富客户端应用程序。JavaFX官方教程(中文版)提供了全面而详细的指导,包括了基础概念、事件处理、控件、图形、布局、动画、多媒体等方面的内容。 在JavaFX基础概念部分,官方教程详细介绍了JavaFX的架构,应用程序的生命周期以及JavaFX的主要组成部分等。 在事件处理和控件方面,官方教程教授了如何处理鼠标、键盘和其他事件。同时,教程也向我们展示了JavaFX控件的样式和功能,并讲解了如何使用不同类型的布局来放置和组织这些控件。 在图形方面,官方教程详细介绍了如何用JavaFX绘制和修改几何形状、颜色和渐变、着色和阴影等。 在布局和动画方面,官方教程教授了如何使用布局来控制窗口中的控件的尺寸和位置等,以及如何利用动画来创建流畅的界面转换和视觉效果。 在多媒体方面,官方教程介绍了JavaFX支持音频、视频和图像处理等的功能,并展示了如何使用JavaFX来载入、播放和控制音频和视频文件。 总之,JavaFX官方教程(中文版)是一份全面而详细的学习资源,对于想要学习JavaFX的开发人员来说非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值