我正在尝试达到类似于marquee的效果-在水平轴上移动的长行(以我为例)的文本。我设法使它起作用,但我不能称其令人满意。

我的Controller类如下所示:

@FXML
private Text newsFeedText;

(...)
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    TranslateTransition transition = TranslateTransitionBuilder.create()
            .duration(new Duration(7500))
            .node(newsFeedText)
            .interpolator(Interpolator.LINEAR)
            .cycleCount(Timeline.INDEFINITE)
            .build();

    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    int width = gd.getDisplayMode().getWidth();

    transition.setFromX(width);
    transition.setToX(-width);
    transition.play();
}


newsFeedText绑定到动态更新的某些文本源,因此它包含各种数量的文本。

我的代码至少有两个缺点:


过渡从-width+widthwidth是显示器的分辨率宽度


如果窗口未全屏显示,则有时文本根本不可见。
如果文本更长,并且newsFeedText宽度大于监视器的分辨率宽度,则过渡将“一半”消失(仍在屏幕上)。


当前Duration不依赖于newsFeedText的宽度。


现在,这没什么大不了的,但是,如果动态计算过渡的fromXtoX,那么它将导致各种字幕的速度。

如何摆脱这些弊端?

最佳答案

我设法将其工作,只有在过渡停止后才能进行任何重新计算,因此我们无法将其cycleCount设置为Timeline.INDEFINITE。我的要求是我可以更改组件内部的文本,所以有fxml接线:

@FXML
private Text node; // text to marquee

@FXML
private Pane parentPane; // pane on which text is placed


起作用的代码是:

transition = TranslateTransitionBuilder.create()
        .duration(new Duration(10))
        .node(node)
        .interpolator(Interpolator.LINEAR)
        .cycleCount(1)
        .build();

transition.setOnFinished(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent actionEvent) {
        rerunAnimation();
    }
});

rerunAnimation();


其中rerunAnimation()是:

private void rerunAnimation() {
    transition.stop();
    // if needed set different text on "node"
    recalculateTransition();
    transition.playFromStart();
}


recalculateTransition()是:

private void recalculateTransition() {
    transition.setToX(node.getBoundsInLocal().getMaxX() * -1 - 100);
    transition.setFromX(parentPane.widthProperty().get() + 100);

    double distance = parentPane.widthProperty().get() + 2 * node.getBoundsInLocal().getMaxX();
    transition.setDuration(new Duration(distance / SPEED_FACTOR));
}

07-28 02:45
查看更多