Как анимировать размер шрифта текстового узла в JavaFX - PullRequest
0 голосов
/ 24 июня 2018

Я хотел бы знать, есть ли способ анимировать размер текста узла (например, 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));
}

1 Ответ

0 голосов
/ 25 июня 2018

Это пример, который реализует пользовательский Interpolator.

Вы можете изучить другие методы в классе 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();
  }
}

Результат

gif

...