我想知道是否有一种方法可以动画化节点的文本大小(例如Label
),例如通过过渡来更改文本大小?我尝试为节点的Timeline
设置一个fontProperty()
,但是什么都没有发生:
Label label = new Label(); // The text node
Font font = Font.font(100); // Change the text size to 100
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(label.fontProperty(), label.getFont())),
new KeyFrame(Duration.millis(1000), new KeyValue(label.fontProperty(), font))
);
我唯一想到的方法是缩放节点的 ACTUAL 大小。但是不利的是,它也会改变节点的布局(位置随其大小而变化)。此外,如果您确实希望文本大小与特定的font-size
值一样大/小,这是不准确的。
Label label = new Label(); // The text node
double size = 2; // Scale the size by 2
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(label.scaleXProperty(), label.getScaleX()),
new KeyValue(label.scaleYProperty(), label.getScaleY())),
new KeyFrame(Duration.millis(1000),
new KeyValue(label.scaleXProperty(), size),
new KeyValue(label.scaleYProperty(), size))
);
还有其他方法可以实现吗?
此过渡中使用的公式(以防万一我忘记或丢失了源代码,所以我可以回到这里并在此处共享它。)
@Override
protected void interpolate(double frac) {
// Determine which is less/greater value between the initial and
// ending value, then get their difference. This is to resolve the
// end value when we either increase or decrease the initial value.
double min = Math.min(start, end); // returns the smaller value
double max = Math.max(start, end); // returns the higher value
double diff = max - min; // the positive difference between the two value.
// Since our start will always be the initial value regardless if
// it is greater or less than the end, we will simply increase or
// decrease its value until it reaches the desired end value.
// Also, computing the difference between their value was to determine
// if they both have equal values, it means (max - min) is always 0
// as well as multiplying it to frac, therefore, there will be a
// 0 value to increase or decrease.
double size = (start == min) ?
start + (diff * frac) : // start is smaller so we'll just increase its value
start - (diff * frac); // decrease if it has the higher value than end
UIcontrol.setFont(Font.font(size));
}
答案 0 :(得分:1)
这是一个实现自定义Interpolator
的示例。
您可以在here的Transition
类中探索其他方法。请注意那里的属性是从类javafx.animation.Animation继承的!
import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.scene.control.Labeled;
import javafx.scene.text.Font;
import javafx.util.Duration;
public class TextSizeTransition extends Transition{
private Labeled UIcontrol; // a little generic -> subclasses: ButtonBase, Cell, Label, TitledPane
private int start, end; // initial and final size of the text
public TextSizeTransition(Labeled UIcontrol, int start, int end, Duration duration) {
this.UIcontrol = UIcontrol;
this.start = start;
this.end = end - start; // minus start because of (end * frac) + start in interpolate()
setCycleDuration(duration);
setInterpolator(Interpolator.LINEAR);
//setCycleCount(100);
// and a lot of other methods
}
@Override
protected void interpolate(double frac) {
// frac value goes from 0 to 1
// when frac is zero -> size is start
// when frac is 1 -> size is end + start
//(that's why we this.end = end - start; above to back to original end value)
int size = (int) ((end * frac) + start);
if(size<=end) {
UIcontrol.setFont(Font.font(size));
}else { // once the size reaches the destination (i.e. end value)
// back to the start size if you want
//UIcontrol.setFont(Font.font(start));
}
}
}
示例
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TextAnimation extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) {
Label label = new Label("Text Size Animation");
Pane root = new Pane(label);
root.setPrefSize(1100, 300);
Scene scene = new Scene(root);
// transit text size from 10 to 100 during 5 seconds
TextSizeTransition trans = new TextSizeTransition(label, 10, 100,Duration.millis(5000));
stage.setScene(scene);
stage.show();
trans.play();
}
}
结果