5.7.3 动画效果

JavaFX提供了对动画效果的支持,可以实现各种不同的动画效果。每个动画效果由多个帧组成。每一帧按照设定的频率进行播放。javafx.animation.Animation类是所有动画效果的父类。通过Animation类的play、pause和stop方法可以开始、暂停和停止动画效果的运行。JavaFX提供了两种类型的动画效果,一种是基于值的自动变化的,另外一种是基于时间线和关键帧的,这两种方式的区别在于动画效果中包含的帧的定义方式不同。

第一种方式需要继承javafx.animation.Transition类并覆写interpolate方法。在创建Transition类的子类对象之后,系统会根据动画效果的持续时间自动计算所需的帧数。在播放每一帧时,interpolate方法会被调用,调用时的参数是当前的动画播放进度,范围在0.0到1.0之间。具体的进度由系统通过不同的插值算法来计算。javafx.animation.Interpolator类的子类表示不同的插值计算算法。通过Transition类的setInterpolator方法可以改变使用的插值算法。比较常用的是由Interpolator.LINEAR表示的线性插值方式。通过Transition类可以实现各种不同的动画效果,比如,实现一个矩形在界面上沿斜线运动,可以使用代码清单5-18中的实现方式。通过setCycleDuration方法把动画效果的周期设为3秒。在interpolate方法的实现中,根据当前的播放进度,通过修改X轴和Y轴坐标的方式把矩形移动到相应的位置上。方法setCycleCount用来设置动画周期的播放次数,Animation.INDEFINITE的含义是无限执行。如果调用setAutoReverse方法并使用“true”作为参数,动画在下一个周期会改变播放的方向。

代码清单5-18 基于值的自动变化的动画效果的示例


final Rectangle rect=new Rectangle(200,100);

final double distanceX=400;

final double distanceY=300;

final Animation animation=new Transition(){

{

setCycleDuration(Duration.millis(3000));

}

protected void interpolate(double frac){

rect.setX(distanceX*frac);

rect.setY(distanceY*frac);

}

};

animation.setCycleCount(Animation.INDEFINITE);

animation.setAutoReverse(true);

animation.play();


JavaFX中提供了一些实现常见动画效果的Transition类的子类。为了实现代码清单5-18中的动画效果,更好的做法是使用javafx.animation.TranslateTransition类。

相对于使用Transition类的做法,第二种做法允许开发人员使用更加灵活的方式为JavaFX中组件的任何属性添加动画效果,这种做法基于javafx.animation.Timeline类来实现。Timeline类表示的是一条时间线,其中包含多个关键帧,即javafx.animation.KeyFrame类的对象。每个KeyFrame类的对象都对应时间线上的某个时间点,以及在这个时间点上属性应该具有的值。属性的值由javafx.animation.KeyValue类的对象来表示。每个KeyFrame类的对象可以包含多个KeyValue类的对象,这些对象表示该关键帧所定义的多个属性的值。在指明了关键帧之后,JavaFX会自动使用插值算法来计算出实现整个动画效果所需的其他帧。这种实现方式的核心在于由开发人员定义整个动画效果中的关键点,由系统负责完成整个动画效果。

代码清单5-19给出了使用Timeline类实现动画效果的示例。在创建Timeline类的对象时,指定了两个关键帧。这两个关键帧对矩形的X轴坐标和填充颜色两个属性添加了动画效果。第一个关键帧对应的时间点是第2秒,此时对属性值的要求是,当动画效果运行到这一帧时,矩形的X轴坐标是100,而填充颜色的值是Color.RED。第二个关键帧对应的时间点是第4秒,此时对属性值的要求是,矩形的X轴坐标是200,而填充颜色的值是Color.WHITE。由于没有指定时间点为第0秒时的关键帧,当动画开始播放时,会以矩形中这两个属性的当前值作为起始值。在整个动画播放过程中,其他帧上的这两个属性的值由系统自动计算。动画的播放效果是,界面上矩形的位置会沿着X轴从坐标0移动到200,同时矩形的填充颜色先从白色逐渐变为红色,再逐渐变回白色。

代码清单5-19 基于时间线和关键帧的动画效果的示例


final Rectangle rect=new Rectangle(200,100,Color.WHITE);

final Animation animation=new Timeline(

new KeyFrame(Duration.seconds(2),new KeyValue(rect.xProperty(),100),new KeyValue(rect.fillProperty(),Color.RED)),

new KeyFrame(Duration.seconds(4),new KeyValue(rect.xProperty(),200),new KeyValue(rect.fillProperty(),Color.WHITE))

);

animation.setCycleCount(Animation.INDEFINITE);

animation.play();